引言

HttpClient是java语言下一个支持http协议的客户端编程工具包,它实现了HTTP协议的所有方法,但是不支持JS渲染。我们在做一些小玩意时,有可能需要登录某些网站获取信息,那么HttpClient就是你的好帮手,废话不多说,进入实战。

一 登录的实际意义

在HTTP横行的今天,我们每天都要登录一些网站,那么登录的意义是什么呢?首先要对cookie要有一定了解。cookie是存放在本地的一些小文件,它由服务器发送命令,浏览器在本地读写。当访问某些网站的时候,浏览器会检查是否有所浏览网站的cookie信息,如果有则在发送访问请求的时候携带上这些内容,服务器可以读取到浏览器发送请求中的cookie信息,在回应请求时可以再写cookie信息。cookie信息包括键值,内容,过期时间,所属网站。

说到这里cookie差不多讲完了,那么登录到底是怎么回事?登录就是服务器向你的浏览器写cookie,如果仅仅是在你的计算机上写cookie,那么别有用心的人伪造一个cookie也有机会登录网站,所以服务器会在内存中保留一份相同的信息,这个过程叫做session会话。如果你在网站点击退出按钮,服务器会把内存中的cookie清除掉,同时清除浏览器中有关登录的cookie。知道了这些,我们就可以上手了。

二 找到登录关键cookie

这里我们可以用wireshark来抓包分析一下。打开知乎首页,打开wireshark,开始监听端口,输入用户名和密码,点击登录,查看wireshark抓到的包。截图如下:

第一张图是浏览器post提交数据。

第二张图是提交的信息,包括_xsrf,password,remember_me,email,注意,提交的信息中包括cookie,_xsrf可以从知乎首页中获取

第三张图是服务器返回的信息,注意它的状态是200,说明是成功的

第四章图是服务器返回的数据,注意它有三条cookie设置,以及带有一个登录成功与否的信息

通过上边的步骤我们能知道什么呢?首先,发送登录请求的时候带有的cookie,以及post数据的格式,其次我们能拿到登录用cookie信息(第四张图)。

三 使用HttpClient构造登录信息

HttpClient是怎样模拟浏览器的呢?首先需要建立一个HttpClient,这个HttpClient是用来模拟一个浏览器。其次构造一个post请求,添加post数据信息以及cookie。详细代码如下:

import org.apache.http.*;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Lookup;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.cookie.DefaultCookieSpecProvider;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;/*** Created by gavin on 15-7-23.*/
public class HttpClientTest {public static void main(String[] args){//创建一个HttpClientRequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();try {//创建一个get请求用来接收_xsrf信息HttpGet get = new HttpGet("http://www.zhihu.com/");//获取_xsrfCloseableHttpResponse response = httpClient.execute(get,context);setCookie(response);String responseHtml = EntityUtils.toString(response.getEntity());String xsrfValue = responseHtml.split("<input type=\"hidden\" name=\"_xsrf\" value=\"")[1].split("\"/>")[0];System.out.println("xsrfValue:" + xsrfValue);response.close();//构造post数据List<NameValuePair> valuePairs = new LinkedList<NameValuePair>();valuePairs.add(new BasicNameValuePair("_xsrf", xsrfValue));valuePairs.add(new BasicNameValuePair("email", "xxxx@xxx.com"));valuePairs.add(new BasicNameValuePair("password", "xxxxx"));valuePairs.add(new BasicNameValuePair("remember_me", "true"));UrlEncodedFormEntity entity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8);//创建一个post请求HttpPost post = new HttpPost("http://www.zhihu.com/login/email");post.setHeader("Cookie", " cap_id=\"YjA5MjE0YzYyNGQ2NDY5NWJhMmFhN2YyY2EwODIwZjQ=|1437610072|e7cc307c0d2fe2ee84fd3ceb7f83d298156e37e0\"; ");//注入post数据post.setEntity(entity);HttpResponse httpResponse = httpClient.execute(post);//打印登录是否成功信息printResponse(httpResponse);//构造一个get请求,用来测试登录cookie是否拿到HttpGet g = new HttpGet("http://www.zhihu.com/question/following");//得到post请求返回的cookie信息String c = setCookie(httpResponse);//将cookie注入到get请求头当中g.setHeader("Cookie",c);CloseableHttpResponse r = httpClient.execute(g);String content = EntityUtils.toString(r.getEntity());System.out.println(content);r.close();} catch (IOException e) {e.printStackTrace();} finally {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}}}public static void printResponse(HttpResponse httpResponse)throws ParseException, IOException {// 获取响应消息实体HttpEntity entity = httpResponse.getEntity();// 响应状态System.out.println("status:" + httpResponse.getStatusLine());System.out.println("headers:");HeaderIterator iterator = httpResponse.headerIterator();while (iterator.hasNext()) {System.out.println("\t" + iterator.next());}// 判断响应实体是否为空if (entity != null) {String responseString = EntityUtils.toString(entity);System.out.println("response length:" + responseString.length());System.out.println("response content:"+ responseString.replace("\r\n", ""));}}public static Map<String,String> cookieMap = new HashMap<String, String>(64);//从响应信息中获取cookiepublic static String setCookie(HttpResponse httpResponse){System.out.println("----setCookieStore");Header headers[] = httpResponse.getHeaders("Set-Cookie");if (headers == null || headers.length==0){System.out.println("----there are no cookies");return null;}String cookie = "";for (int i = 0; i < headers.length; i++) {cookie += headers[i].getValue();if(i != headers.length-1){cookie += ";";}}String cookies[] = cookie.split(";");for (String c : cookies){c = c.trim();if(cookieMap.containsKey(c.split("=")[0])){cookieMap.remove(c.split("=")[0]);}cookieMap.put(c.split("=")[0], c.split("=").length == 1 ? "":(c.split("=").length ==2?c.split("=")[1]:c.split("=",2)[1]));}System.out.println("----setCookieStore success");String cookiesTmp = "";for (String key :cookieMap.keySet()){cookiesTmp +=key+"="+cookieMap.get(key)+";";}return cookiesTmp.substring(0,cookiesTmp.length()-2);}
}

代码的流程是:

  1. 从知乎首页获取xsrf信息。

  1. post请求当中需要cookie信息,但是我们第一步中没有得到cookie,请在浏览器中自行找到cookie添加进去,上边的cookie是我找到的。

  2. 提交post请求,得到登录用cookie

  3. 随便找一个需要登录的子页面,将得到的cookie写入到请求头中,提交请求,查看是否已经登录成功

四 结果验证

第一张图显示得到cookie并登录成功

第二张图显示已经进入需要登录的界面

总结

  1. 当我们需要登录一个界面获取信息的时候,我们要知道登录实际上做了什么,那就是读写cookie,post数据。

  2. 获取cookie时,需要从响应头中获取,当服务器发来新的cookie信息时需要及时写入。

  3. 当我们能登录一个网站的时候,如何对其内容进行操作,这里推荐jsoup,良心库,仿jquery操作模式。

更多文章:http://blog.gavinzh.com

HttpClient4.4 登录知乎(详细过程)相关推荐

  1. HttpClient4.4.1模拟登录知乎

    HttpClient4.4.1模拟登录知乎 一,登录要Post的表单数据是什么 这部分可以使用Wireshark工具来抓包就可以了,发现需要以下数据: "_xsrf" = xxxx ...

  2. Python爬虫初学(三)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  3. 小试牛刀:使用Python模拟登录知乎

    2019独角兽企业重金招聘Python工程师标准>>> 作者:刘帝伟(微博:@拾毅者) 原文链接:点击这里 BitTiger尊重原创版权,转载已经过授权. 最近突然对爬虫兴趣倍增,主 ...

  4. Python爬虫:模拟登录知乎完全详解

    [源码在最下面] 知乎登录分为邮箱登录和手机登录两种方式,通过浏览器的开发者工具查看,我们通过不同方式登录时,网址是不一样的.邮箱登录的地址email_url = 'https://www.zhihu ...

  5. 使用Python模拟登录知乎

    环境与开发工具 在抓包的时候,开始使用的是Chrome开发工具中的Network,结果没有抓到,后来使用Fiddler成功抓取数据.下面逐步来细化上述过程. 模拟知乎登录前,先看看本次案例使用的环境及 ...

  6. HBase 1.2.6 完全分布式集群安装部署详细过程

    2019独角兽企业重金招聘Python工程师标准>>> Apache HBase 是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统,是NoSQL数据库,基于Google Big ...

  7. 【Linux】【服务器】 CentOS7下安装MySQL(版本8.0)详细过程步骤

    一.检查是否安装过mysql [Linux][服务器]CentOS7下卸载MySQL详细过程步骤 二.下载Linux下的Mysql包,打开Mysql官网 1.MySQL官网 2.滑到最后,点击MySQ ...

  8. 吴恩达登录知乎,亲自回答如何系统学习机器学习

    如何系统地学习机器学习?知乎里有很多回答,近日,吴恩达老师亲自在知乎回答了这个问题: 作者:吴恩达 链接:https://www.zhihu.com/question/266291909/answer ...

  9. 网站渗透测试原理及详细过程

    渗透测试实战 site:baidu.com 渗透测试思路 site:baidu.com 带你入门渗透测试的5个项目:https://www.jianshu.com/p/5b82e42ae346 渗透测 ...

最新文章

  1. -bash: fultter: command not found
  2. cpu,内存,虚拟内存,硬盘,缓存之间是什么关系??
  3. arcgis python 保存当前窗口图形为jpg
  4. VTK:可视化算法之FireFlow
  5. 如何自定义SAP Spartacus 产品明细的url pattern
  6. javascript设计模式--命令模式
  7. sql实现对多个条件分组排序方法和区别
  8. C# 多线程同步和线程通信
  9. 为什么需要一个激励函数
  10. 如何通过XMind 实践OKR 工作法
  11. 最全面的linux网站
  12. word是多线程的程序_线程的基本概念,实现多线程的四种基本方式
  13. Android蓝牙开发与串口蓝牙通讯
  14. 自发光物体能被烘焙之后是否会影响周围的物体
  15. wuc-tab标签点击不了_微信公众号新增标签功能,格力被中国移动取消竞标资格,全国电子无偿献血证上线,QQ新增辣椒酱表情,这就是今天的其他大新闻!...
  16. 深入好文:数字经济技能:基于角色的数字技能培养方法、行业趋势、未来及未来的关键角色、这些角色的学习路径
  17. matlab读取Ansys仿真数据实例演示
  18. 【高等数学】二元函数的奇偶性与对称性
  19. 【数据结构与算法】二叉树题目很难?一句话秒杀基础二叉树题目
  20. 南阳理工628解题报告(小媛在努力)

热门文章

  1. 科益展机器人_Smartguy robotics 2021年校园领军(实习)精英计划
  2. Nginx学习3:反向代理实例
  3. Java项目:资源下载工具(java+swing)
  4. insert 语句的选择列表包含的项多于插入列表中的项_如何定义和使用Python列表(Lists)
  5. 【Linux】Linux 简单操作指令之磁盘管理
  6. nodejs回调函数理解
  7. UITextView添加占位字符
  8. 苹果禁止使用热更新 iOS开发程序员新转机来临
  9. CocoaPods远程私有库
  10. 各种小的 dp (精)