知乎模拟登陆java编写_HttpClient 模拟登陆知乎

最近做爬虫相关工作,我们平时用HttpWebRequest 比较多,每一个Url都要创建一个HttpWebRequest实例,

而且有些网站验证比较复杂,在登陆及后续抓取数据的时候,每次请求需要把上次的Cookie传递给这次请求。

记得这篇博客(http://www.cnblogs.com/dudu/archive/2013/03/05/httpclient.html)结尾,dudu总结了:

HttpClient最与众不同的地方是同一个HttpClient实例可以发出多次请求,每次请求是可以是完全不同的URL。

而一个HttpWebRequest实例对应于一个Url的一次请求。这才是HttpClient与HttpWebRequest的最大区别所在。

那么为什么不用HttpClient呢?

本着学习的目的,那我就拿知乎练习一下,看看HttpClient好用否?

1,分析登陆页:https://www.zhihu.com/#signin

9aedefb3c552bc7a1226ce0d39b639c4.png

根据上图设置 DefaultRequestHeaders

HttpClient h = newHttpClient(newHttpClientHandler

{//CookieContainer = cookies,

AutomaticDecompression = DecompressionMethods.GZip //防止返回的json乱码

|DecompressionMethods.Deflate

});

h.DefaultRequestHeaders.Add("UserAgent", Configs.ChromeAgent);

h.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");

h.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, sdch");

h.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");//1.首页

var response = awaith.GetAsync(index);string content = awaitresponse.Content.ReadAsStringAsync();if(response.IsSuccessStatusCode)

{//获取隐藏的input值

HtmlDocument doc = newHtmlDocument();

doc.LoadHtml(content);var xsdf = DocumentHelper.GetInputValue(doc, "_xsrf");//登录需要

nameValue["_xsrf"] =xsdf;

}else{return null;

}

2,分析登陆页:https://www.zhihu.com/login/phone_num(我这里是手机和密码登录):

d7e5ad5b6be14a25dd5c132646b86ea1.png

分析:除了要设置DefaultRequestHeaders,还需获取_xsrf的值,

这里还需注意:1, Content-Type: application/x-www-form-urlencoded; charset=UTF-8 该如何设置? 参考地址:http://ronaldrosiernet.azurewebsites.net/Blog/2013/12/07/posting_urlencoded_key_values_with_httpclient

2, 登录返回的JSON结果是乱码,该如何处理? 参考地址:http://stackoverflow.com/questions/9242472/retrieve-json-data-with-httpclient

//2.登陆

h.DefaultRequestHeaders.Clear();

h.DefaultRequestHeaders.Add("UserAgent", Configs.ChromeAgent);

h.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest");

h.DefaultRequestHeaders.Add("Origin", index);

h.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");

h.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, sdch");

h.DefaultRequestHeaders.Add("Accept", "*/*");//post参数

nameValue["password"] =PassWord;

nameValue["captcha_type"] = "cn";

nameValue["remember_me"] = "true";

nameValue["phone_num"] =Phone;

StringBuilder sb= newStringBuilder();foreach (var key innameValue.AllKeys)

{

sb.AppendFormat("{0}={1}&", key, nameValue[key]);

}var str = sb.ToString().TrimEnd('&');var request = newHttpRequestMessage(HttpMethod.Post, login);var requestContent =str;

request.Content= new StringContent(requestContent, Encoding.UTF8, "application/x-www-form-urlencoded");

response= awaith.SendAsync(request);

content= awaitresponse.Content.ReadAsStringAsync();var dic =DocumentHelper.JsonToDic(content);if (dic.ContainsKey("msg"))

{if (dic["msg"] != "登陆成功")//登录过于频繁,请稍等重试;errcode:100030

{

Console.WriteLine(dic["msg"]);return null;

}

}

3. 登录成功后,后面就由大家随便折腾了。这里获取登陆后的首页信息吧。

//3.抓取首页

h.DefaultRequestHeaders.Clear();

h.DefaultRequestHeaders.Add("UserAgent", Configs.ChromeAgent);

h.DefaultRequestHeaders.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");

h.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, sdch");

h.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

response= awaith.GetAsync(index);

content= await response.Content.ReadAsStringAsync();

4,我也不对数据做处理了,看看结果:

bf6c2a00f1243e5cd8c1a1f6ca887284.png

上图是调试状态下的可视化工具视图。

源码地址:https://github.com/zzhi/Spider4Net, 里面也包含了用HttpWebRequest 方式登录的代码。

以上就是所有了,如果有时间给大家讲讲登录验证码的识别,但是这个略麻烦,需要根据具体网站的验证码训练一个验证码库,

复杂的无法识别的验证码就只能用打码兔了,其实也可以自己写个类似打码兔的软件,但需要有人值守,人工识别验证码。

这这么点东西,昨晚花费了3小时(9-12),今早写博客又花费了1小时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值