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呢?
源码地址:https://github.com/zzhi/Spider4Net
本着学习的目的,那我就拿知乎练习一下,看看HttpClient好用否?
1,分析登陆页:https://www.zhihu.com/#signin
根据上图设置 DefaultRequestHeaders
HttpClient h = new HttpClient(
new HttpClientHandler
{
//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 = await h.GetAsync(index);
string content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
//获取隐藏的input值
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(content);
var xsdf = DocumentHelper.GetInputValue(doc, "_xsrf");//登录需要
nameValue["_xsrf"] = xsdf;
}
else
{
return null;
}
2,分析登陆页:https://www.zhihu.com/login/phone_num(我这里是手机和密码登录):
分析:除了要设置DefaultRequestHeaders,还需获取_xsrf的值<input type="hidden" name="_xsrf" value="3bc639713d3f8bb899009a7dfa37f9d2"/>,
这里还需注意: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 = new StringBuilder();
foreach (var key in nameValue.AllKeys)
{
sb.AppendFormat("{0}={1}&", key, nameValue[key]);
}
var str = sb.ToString().TrimEnd('&');
var request = new HttpRequestMessage(HttpMethod.Post, login);
var requestContent = str;
request.Content = new StringContent(requestContent, Encoding.UTF8, "application/x-www-form-urlencoded"); response = await h.SendAsync(request);
content = await response.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 = await h.GetAsync(index);
content = await response.Content.ReadAsStringAsync();
4,我也不对数据做处理了,看看结果:
上图是调试状态下的可视化工具视图。
源码地址:https://github.com/zzhi/Spider4Net, 里面也包含了用HttpWebRequest 方式登录的代码。
以上就是所有了,如果有时间给大家讲讲登录验证码的识别,但是这个略麻烦,需要根据具体网站的验证码训练一个验证码库,
复杂的无法识别的验证码就只能用打码兔了,其实也可以自己写个类似打码兔的软件,但需要有人值守,人工识别验证码。
这这么点东西,昨晚花费了3小时(9-12),今早写博客又花费了1小时。
HttpClient 模拟登陆知乎的更多相关文章
- Python 爬虫模拟登陆知乎
在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...
- python模拟登陆知乎并爬取数据
一些废话 看了一眼上一篇日志的时间 已然是5个月前的事情了 不禁感叹光阴荏苒其实就是我懒 几周前心血来潮想到用爬虫爬些东西 于是先后先重写了以前写过的求绩点代码 爬了草榴贴图,妹子图网,后来想爬婚恋网 ...
- 使用OKHttp模拟登陆知乎,兼谈OKHttp中Cookie的使用!
本文主要是想和大家探讨技术,让大家学会Cookie的使用,切勿做违法之事! 很多Android初学者在刚开始学习的时候,或多或少都想自己搞个应用出来,把自己学的十八般武艺全都用在这个APP上,其实这个 ...
- Scrapy 模拟登陆知乎--抓取热点话题
工具准备 在开始之前,请确保 scrpay 正确安装,手头有一款简洁而强大的浏览器, 若是你有使用 postman 那就更好了. Python 1 scrapy genspid ...
- python模拟登陆知乎
---恢复内容开始--- 在完成前面的阶段的任务之后,我们现在已经能够尝试着去模拟登录一些网站了.在这里我们模拟登录一下知乎做一下实验.笔者在这里总共用了三天多的时间,下面给大家分享一下笔者是怎么一步 ...
- 第十二篇 requests模拟登陆知乎
了解http常见状态码 可以通过输入错误的密码来找到登陆知乎的post:url 把Headers拉到底部,可以看到form data _xsrf是需要发送的,需要发送给服务端,否则会返回403错误,提 ...
- HTTPCLIENT 模拟登陆
第一步构建忽略https验证的httpclient public static CloseableHttpClient getHttpClient() throws Exception { SSLCo ...
- python使用requests模块模拟登陆知乎
from bs4 import BeautifulSoup import requests import time def captcha(captcha_data): with open(" ...
- httpClient模拟登陆校内某系统
package com.huowolf; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpE ...
随机推荐
- asp.net登录状态验证
文章:ASP.NET 登录验证 文章:ASP.NET MVC下判断用户登录和授权状态方法 文章:.net学习笔记---HttpHandle与HttpModule 第一篇文章,介绍了 1)早期的Base ...
- RAID卡服务器安装2003教程
这里先讲讲安装系统的几个思路: 1.U盘安装法(U盘只做可启动PE,常用的大白菜,IT天空,老毛桃.....拷贝系统ISO镜像到U盘,进入PE之后找到ISO,用虚拟光驱加载,运行WIN系统安装器 ...
- 新浪 ip 地址库
API地址:http://int.dpool.sina.com.cn/iplookup/iplookup.php 帮助 1 2 3 4 5 6 7 8 function get_location($i ...
- puppeteer设置代理并检查代理是否设置成功
1. 设置代理: 这一步超级简单,但我掉到了坑里并扑腾了小一天的时间,那就是:箭头指向处一定一定不要加空格!!! 2. 检查代理是否设置成功: 在打开的浏览器里,打开百度,输入ip,如果查出来的结果跟 ...
- 第73天:jQuery基本动画总结
一.DOM对象跟jQuery对象相互转换 jQuery对象转换成DOM对象: 方式一:$(“#btn”)[0] 方式二:$(“#btn”).get(0) DOM对象转换成jQuery对象: $(doc ...
- 当使用listIterator进行迭代时候 list的迭代器可以在创建迭代器对象后 添加数据 但打印的时候不显示添加后的数据。 collection 的iterator迭代器不能添加数据 。list的对象与collection的实例对象都不能在创建迭代器后添加数据 list的迭代器保存的是循环前的数据长度
- BZOJ 2006 超级钢琴(堆+主席树)
很好的一道题. 题意:给出长度为n的数列,选择k个互不相同的区间,满足每个区间长度在[L,R]内,求所有选择的区间和的总和最大是多少.(n,k<=5e5). 首先将区间和转化为前缀和之差,那么我 ...
- 在虚拟机上安装linux系统
1.安装linux服务器,内存4G,默认典型,next安装程序光盘影像文件,next选版本 2.6.x内核64位,next选择虚拟机位置(至少10G),next最大磁盘20G,选择单文件,next自定 ...
- 洛谷 P2258 子矩阵
题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...
- 函数式编程(1)-高阶变成(1)-map/reduce
map/reduce Python内建了map()和reduce()函数. 如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Processing on ...