SuperWebClient -一个基于CURL的.NET HTTP/HTTPS模拟神组件(2)
今天我们讨论SuperWebClient组件使用中的几个简单主题
1: UserAgent
2: Cookies
3: POST登录
1:UserAgent
这个是客户端标识信息,此信息是用于鉴别正在访问WEB服务的客户端的类型,下面我们通过抓包工具Fiddler,来获取几个典型浏览器
的此项信息是怎么样的. Fiddler是一个.NET的开源HTTP/HTTPS协议分析软件,后来被收购后就没开源了好像。
Fiddler 下载地址 http://www.telerik.com/fiddler,运行后如下所示
首先我们打开IE浏览器-输入博客园网站,就会看到Fiddler抓到很多数据包,我们选取首页的那条就可以查看具体的http 请求信息
我们可以知晓IE浏览器的userAgent信息如下
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
(机器上IE版本和安装的软件不一样,USER-AGENT也会有些许差异)
我们在看基于谷歌CHROME浏览器的类似下面
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.48 Safari/537.36
还有众多猎豹,火狐,遨游和其它都有自己的一些附加信息在User-Agent中,那这个东西可能会有哪些用途了。
一般而言,WEB服务器并不看重这个信息,但有些也会检查,并根据不同的客户端给出适当的输出反馈,另外就是客户端JS脚本会根据
这个信息做些兼容性的检查和调整。
对于爬虫比如百度,谷歌或其它都有自己独特的userAgent信息,SuperWebClient默认模拟的是IE浏览器的,当然,你完全可以设置
模拟任何信息,比如下面这样 SuperWebClient 应用代码示例如下
注意代码红色区域的部分,本来是作为后面的主题来讨论的,现在是为了演示如何用FIDDLER抓取到SuperWebClient的请求包才会提前标注下
默认是模拟的IE浏览器的,下面我修改这个User-Agent信息为 “i-love-you”
- // 首先构建一个 嗨 对象-也就是模拟访问的输入对象
- HttpInput hi = new HttpInput();
- // 需要初始化这个hi,设置是否启用HTTP 1.1,后面是连接和传输超时设定(秒)
- HttpManager.Instance.InitWebClient(hi, true, 60, 60);
复制代码
// 代理设置-不然FIDDLER是无法抓取到的
hi.EnableProxy = true;
hi.ProxyIP = "127.0.0.1";
hi.ProxyPort = 8888;
hi.UserAgent = "i-love-you";
// 接下来就是设置访问的URL,和其它譬如UserAgent,Cookies,Proxy....等等各种特性的设置
// 一般,我们就设置Url 访问路径,其它都是在有需要的时候设置就可以了
- hi.Url = "http://www.cnblogs.com/";
- // 有输入对象,就有对应的输出对象-注意,这个方法是阻塞的,只到结果反馈回来
- // 所以,你可以把代码放入独立的线程或是线程池中进行数据的采集
- HttpOutput ho = HttpManager.Instance.ProcessRequest(hi);
- if (ho.IsOK)
- {
- // 如果HO的标志IsOK成立,则页面访问是成功的,否则就是页面访问失败
- // 遇到失败-你可以自己做后续处理,比如重发起请求或是写LOG
- richTextBox1.Text = ho.TxtData;
- }
- else
- {
- richTextBox1.Text = "页面访问错误";
- }
- // 最后销毁对象
- hi.Dispose();
你可以根据需要伪装成任何需要的,比如微信,陌陌啥的特有的信息。
2:Cookie
SuperWebClient 默认处理WEB服务器发送来的COOKIE,无需你自己大费脑筋,那从服务器发来的COOKIE信息怎么读取呢
HttpOutput ho = HttpManager.Instance.ProcessRequest(hi);
if (ho.IsOK)
{
richTextBox2.Text = ho.Cookies; // 如果HO的标志IsOK成立,则页面访问是成功的,否则就是页面访问失败
// 遇到失败-你可以自己做后续处理,比如重发起请求或是写LOG
richTextBox1.Text = ho.TxtData;
}
在输出对象的ho.Cookies属性里面哦。
比如访问C#蚁工窝 http://www.csharpworker.com/
拿到的cookies是
hTQ9_2132_pc_size_c=0;hTQ9_2132_onlineusernum=2;hTQ9_2132_lastact=1488261049%09forum.php%09;hTQ9_2132_sid=mRojS6;hTQ9_2132_lastvisit=1488257449;hTQ9_2132_saltkey=p7EgLlZg;
WEB服务器会在不同的请求多次发送不同的cookies, SuperWebClient的输出对象httpoutput只是当次请求时的服务器发送COOKIES信息,不会累计,虽然SuperWebClient内部会累计所有从服务器发送的COOKIE并在向服务器提交时一并回传回去,但是目前并没有提供读取所有累计COOKIE的方法,你可以自己收集每次请求的反馈对象httpoutput中的COOKIES信息,一般而言,我不怎么理会这个东西,除非你是要保存COOKIES另做它用。
3:POST登录
一般情况下,如无意外,WEB服务的很多操作请求都是基于POST协议的,AJAX也是,极少是基于GET协议的,因为请求字符串是有长度限制的
大量的参数需要通过POST来发送,接下来,我们看看SuperWebClient如何通过POST方式来登录一个网站,在展示之前,我们有必要分析网站登录
的请求协议,然后使用SuperWebClient进行模拟。
我们就以登录博客园的过程来说明下,首先我们用Fiddler进行抓取博客园的登录协议,注意,如果你抓取不到博客园的登录协议,请看如下2个FIDDLER中针对的两个最常见的问题,因为博客园登录是采用的HTTPS,所以需要开启FIDDLER中相应的HTTPS解码选项。
点击FIDDLER菜单的 TOOL->TERERIK FIDDLER OPTIONS
如果你遇到可以抓取,但是发现无法解码的情况,那就是你的证书问题,证书问题-可以参阅http://blog.csdn.net/chjqxxxx/article/details/53666175 这里-重新构建证书-问题就会解决
这里是博客园的登录协议
POST https://passport.cnblogs.com/user/signin HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: zh-cn
Referer: https://passport.cnblogs.com/user/signin?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F
Accept: application/json, text/javascript, */*; q=0.01
verificationtoken: _Q9B84azUZnUTIffmygxm8pONeAnXanp7gw7sqep3b3Lqk-opvj5wPgeAN6SM6lN1qFi6y8-36GAyjMDYYBuf_cy6iE1:fmSuVFj_iIGBnMV7N3TydHUuc8ORlIkNw7eSCsGqwV2BX7lM64bNoMV0X3S-t2-rlDcBpfuYnK3_In_fMNTFaPhE3Cw1
Content-Type: application/json; charset=utf-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Host: passport.cnblogs.com
Content-Length: 386
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: Hm_lvt_cc17b07fc9529e3d80b4482c9ce09086=1482645471; _ga=GA1.2.806287383.1482645352; __gads=ID=cde93307386572b7:T=1488262791:S=ALNI_MbB1oiDaPhuYt-REwWv3uYFQG8-AA; AspxAutoDetectCookieSupport=1; SERVERID=227b087667da6f8e99a1165002db93f6|1488285061|1488285061 {"input1":"a9Q+6M4EwC0HlHafyL8GYvd5zcFP+tUMV+F2P+aF0FdzrtY9nqPdkjCDctPQlY37EI/VzpLc9z+SAKXaWpWa0yDUM3USN+b7W+m6t7p8qRS+nuHu1G6wJ34IyuAruQ5gE3+r30PKy65q9dD0F5ruOSZizIYgCvm2/WrQfQsdYiQ=","input2":"fGOIEUEG5HP6tt3c/q9z0DuLyc9qeq0GiJQyTGNhTL/sCriRomR2G8gtn+AurDFzH/dDzMOYrBfEJ97n454gg8Ppd5cRe3qaNBTPebCJrIK3chv/Mupe+liFvEu6MwOgPqFBRm6GQCSZBHaVfRpHBKYrQkEaWRZ6ItSjKCBKpQc=","remember":false}
账号和密码都是经过加密处理的,至于加密过程,你需要仔细分析博客园的JS代码,这里我们仅仅是用来说明如何使用SuperWebClient进行
POST表单登录,所以对于账号,密码的加密分析略过,如果后面特别有空闲,我会补充一篇文章分析博客园的账号,密码加密,主要是对相关
JS代码的调试和分析。
那么使用 SuperWebClient如何进行博客园登录了。很简单。
HttpInput hi = new HttpInput(); HttpManager.Instance.InitWebClient(hi, true, 60, 60);
// 这里设置博客园登录URL
hi.Url = "https://passport.cnblogs.com/user/signin";
hi.Refer = "https://passport.cnblogs.com/user/signin?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F";
// 我们伪造下来路,证明我们是从哪里来的,根据协议
// POST数据 hi.PostData = "input1=a9Q+6M4EwC0HlHafyL8GYvd5zcFP+tUMV+F2P+aF0FdzrtY9nqPdkjCDctPQlY37EI/Vzp"
+"Lc9z+SAKXaWpWa0yDUM3USN+b7W+m6t7p8qRS+nuHu1G6wJ34IyuAruQ5gE3+r30PKy65q9dD0F5ruOSZizIYgCvm2/WrQfQsdYiQ="
+"&input2=fGOIEUEG5HP6tt3c/q9z0DuLyc9qeq0GiJQyTGNhTL/sCriRomR2G8gtn+AurDFzH/dDzMOYrBfEJ97n454gg8Ppd5cRe3qa"
+"NBTPebCJrIK3chv/Mupe+liFvEu6MwOgPqFBRm6GQCSZBHaVfRpHBKYrQkEaWRZ6ItSjKCBKpQc="
+"&remember=false"; HttpOutput ho = HttpManager.Instance.ProcessRequest(hi);
if (ho.IsOK)
{ richTextBox1.Text = ho.TxtData;
}
else
{
richTextBox1.Text = "页面访问错误";
} // 最后销毁对象
hi.Dispose();
hi.PostData="设置POST表单数据" 格式是: key1=value1&key2=value2.....依次若干
今天的主题分享完了,有了今天的一些东西,你已经能处理大部分的模拟请求,SuperWebClient的大部分功能也是围绕目前的GET,POST服务。
SuperWebClient -一个基于CURL的.NET HTTP/HTTPS模拟神组件(2)的更多相关文章
- SuperWebClient -一个基于CURL的.NET HTTP/HTTPS模拟神组件(1)
我们都知道,不管你是做爬虫也好,采集工具也罢,它们的HTTP/HTTPS模拟访问总是一个基础问题,我估计有很多人和我一样,虽然这样,那样的内置或是第三方类库用了很多,却总是会有一些不如意的问题存在,亦 ...
- 一个基于nodejs,支持http/https的中间人(MITM)代理,便于渗透测试和开发调试。
源码地址:https://github.com/wuchangming/node-mitmproxy node-mitmproxy node-mitmproxy是一个基于nodejs,支持http/h ...
- 手把手写一个基于Spring Boot框架下的参数校验组件(JSR-303)
前言 之前参与的新开放平台研发的过程中,由于不同的接口需要对不同的入参进行校验,这就涉及到通用参数的校验封装,如果不进行封装,那么写出来的校验代码将会风格不统一.校验工具类不一致.维护风险高等其它因素 ...
- Yoshino: 一个基于React的可定制化的PC组件库
Github: https://github.com/Yoshino-UI... Docs: https://yoshino-ui.github.io/#/ Cli-Tool: https://git ...
- 【原创】强撸基于 .NET 的 Redis Cluster 集群访问组件
Hello 大家好,我是TANZAME,我们又见面了.今天我们来聊聊怎么手撸一个 Redis Cluster 集群客户端,纯手工有干货,您细品. 随着业务增长,线上环境的QPS暴增,自然而然将当前的单 ...
- 模拟登录神器之PHP基于cURL实现自动模拟登录类
一.构思 从Firefox浏览器拷贝cURL命令(初始页.提交.提交后) 自动分析curl形成模拟登录代码 默认参数:ssl/302/gzip 二.实现 接口 (一)根据curl信息执行并解析结果 p ...
- 简单的php基于curl的反向代理程序
起因: 经理:需要实现一个反向代理? 我: 简单,nginx分分钟配置好. 经理:嗯?没有nginx? 我: nodejs也行啊,网上有例子分分钟搞定. 经理:嗯?只有虚拟主机,只能上传php程序? ...
- SDKMAN一个基于命令行界面的SDK用户环境管理程序
1.背景 使用过Python开发的朋友,应该了解到Python2和Python3语法的差异,有时候从网上下载了基于不同解释器的代码,要来回切换版本, 使用起来不是很方便,有时候甚至很麻烦.于是有人发明 ...
- psutil一个基于python的跨平台系统信息跟踪模块
受益于这个模块的帮助,在这里我推荐一手. https://pythonhosted.org/psutil/#processes psutil是一个基于python的跨平台系统信息监视模块.在pytho ...
随机推荐
- 设置git账号并生成新的ssh(切换电脑用户之后)
1.设置账号 2.设置邮箱 3.检查确认 4. 5.check-----成功~
- [题解]bzoj 1861 Book 书架 - Splay
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1396 Solved: 803[Submit][Stat ...
- iOS MVVM 前世今生
MVVM,Model-View-ViewModel,一个从 MVC 模式中进化而来的设计模式,最早于2005年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出.
- WPF中ContextMenu通过CommandParameter传参
场景:ListBox中有个ContextMenu,希望点击其中一个菜单项的时候把ListBox当做CommandParameter传递给Command,但是发现无论是通过ElementName还是Re ...
- iOS 调试 之 打印
参考:http://m.blog.csdn.net/blog/HookyStudent/42964317 参考:http://m.blog.csdn.net/blog/laencho/25190639 ...
- PHP中文件包含的路径问题
在程序中当前文件夹下文件路径可以表示为3种:1)绝对路径,2)相对路径,3)直接文件名 例如在/var/www下的a.php:1)/var/www/a.php 2)./a.php 3)a.php 在P ...
- NodeMCU之旅(三):响应配置按钮
引言 在之前的代码中,要连接的WIFI信息都已写死在代码里,这显然不能适应我们的需求.所以需要想个办法让用户可以配置这些信息. WIFI工作模式 NodeMCU支持STATION,SOFTAP,STA ...
- MFC中在基于对话框的窗体中使用CFileDialog导致菜单栏变灰的解决方案
CSDN的博客编辑器实在是难用……转战博客园 直接把CSDN发的搬过来了 ————————————————————————————我是分割线———————————————————————————— 第 ...
- jQuery 判断checkbox是否被选中 4种方法
下午写JS验证,有一个需求需要判断 checkbox是否被选择,查阅相关资料后,总结以下4种方法,分享给大家. <!DOCTYPE html> <html lang="en ...
- Js获取复选框checkbox的值
var emps= $("input[name='emp']:checked"); var employee= ""; emps.each(function() ...