原理

我们知道,一般需要登录的网站,服务器和客户端都会有一段时间的会话保持,而这个会话保持是在登录时候建立的, 服务端和客户端都会持有这个KEY,在后续访问时,都需要核对这两个KEY是否一致。 而客户端的这个KEY就存在cookie中。 因此,我们需要获取登录后的cookie值,并在后续的访问中,都添加这个cookie。这样才能做到模拟登录的效果。

例子:

我们以获取博客园首页的园龄为例。需要做三步

1. 模拟登录博客园

2. 构建个人主页的Request请求,包括cookie

3. 获取个人主页的数据后, 分析页面,并获取园龄的数据。

代码如下:

static void Main(string[] args)
{
//string html= Hello();
string html = LoginSimulation();
Console.WriteLine(html);
Console.Read();
}
static string LoginSimulation()
{ string url = "https://passport.cnblogs.com/user/signin";
string postData = "{\"input1\":\"MvxmwEWfUF26IvKNa1dUiZn1xmSBhNW0wJyoaUlDPXoh+Mb+z2eZK3r3c9Jd0aT0/Wzz3ht7LMeTllu8ISY9nfQIuKB0C19Y9/IfKYSktpZZOVaKx/XP3i/mGxXC3K5m2la91ViRh3BO36xT4E98dbqVHPtynjuNafuVIBF5a2M=\",\"input2\":\"xxxx":false}"; //1.获取登录Cookie
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";// POST OR GET, 如果是GET, 则没有第二步传参,直接第三步,获取服务端返回的数据
req.AllowAutoRedirect = false;//服务端重定向。一般设置false
req.ContentType = "application/x-www-form-urlencoded";//数据一般设置这个值,除非是文件上传 byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length;
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close(); HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
string cookies = resp.Headers.Get("Set-Cookie");//获取登录后的cookie值。 //2.登录想爬取页面的构造,主要多一个Cookie的构造
string contentUrl = "https://home.cnblogs.com/u/xinjian/";
HttpWebRequest reqContent = (HttpWebRequest)WebRequest.Create(contentUrl);
reqContent.Method = "GET";
reqContent.AllowAutoRedirect = false;//服务端重定向。一般设置false
reqContent.ContentType = "application/x-www-form-urlencoded";//数据一般设置这个值,除非是文件上传 reqContent.CookieContainer = new CookieContainer();
reqContent.CookieContainer.SetCookies(reqContent.RequestUri, cookies);//将登录的cookie值赋予此次的请求。 HttpWebResponse respContent = (HttpWebResponse)reqContent.GetResponse();
string html = new StreamReader(respContent.GetResponseStream()).ReadToEnd(); //3. 分析读取该页面的数据,可以使用HtmlAgilityPack第三方类,这里比较简单,自己写个获取方法就行
string age= GetVal(html, "<span title='入园时间:2010-6-28'>", "</span>");
return age;
}

注意事项

1. 本次模拟登录,我发现chrome的开发人员工具,并没有抓到真正的Post包,和我之前遇到的情况一样, 后来还是使用了httpwatch后,才抓到了真正的数据包。博客园做的不错,提交的数据进行了加密。 当然我的密码我也已经改成了XXX,用户需要运行的话,需要自行抓包获取对应的postData。

2. 针对cookie的赋值,主要由这两句完成

            reqContent.CookieContainer = new CookieContainer();
reqContent.CookieContainer.SetCookies(reqContent.RequestUri, cookies);//将登录的cookie值赋予此次的请求。

但是听说C#封装的不是很好,有时候会漏掉数据,但我目前还没遇到过, 如果遇到,需要将cookie的string手工转换成CookieCollection,并赋予CookieContainer。

3. 针对ASP.NET的网页, 会存在__VIEWSTATE & __EVENTVALIDATION 这两个post字段, 对于没建立会话时,这两个值是不会变的,而一旦建立会话(模拟登陆后),每次访问的页面,这两个值都会改变, 解决办法是先使用GET获取该页面的数据后,获取这两个字段的值, 然后在post的时候,进行赋值。

4. 在遇到500错误的时候,说实话,我也很头疼,不知道如何调试,但我总结下来,一定是request构建的不对。主要查看如下问题:

4.1. 对比post的数据的key和value,看看格式是否正确,如是否进行了编码 WebUtility.UrlEncode()。

4.2. 对比post的数据的,是否Post了全部的数据, 当然这里不光是当前页面,有时候还会用到其他页面,我举个例子, 我在订单页面上传附件, 在附件上传页面,发现并没有Post订单的id,那么这个时候,就需要查找订单的id服务端是什么时候获取的,这个时候就需要猜了,有可能是在打开订单页面的时候,服务端就把此id存储到session中了。所以先需要模拟打开订单页面,然后在模拟订单附件上传的post。

4.3 注意是是否犯了__VIEWSTATE & __EVENTVALIDATION的错误,注意,针对数据型的post,需要进行urlEncode。

4.4 Request的Head是否构建全了, 有时候客户端会提交自定义的head,注意查看。同时UserAgent有时候也会需要进行变化,但目前我还没遇到过。

4.5. 如果确定Post的数据全了,并且还是500错误的话,考虑下是否cookie有问题,虽然我还没遇到过。

最新文章

  1. 深入理解C++对象模型
  2. Bestcoder Round 47 &amp;&amp; 48
  3. HDU5831
  4. 形行色色的下拉菜单(HTML/CSS JS方法 jQuery方法实现)
  5. LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题
  6. 集合框架null与size=0
  7. XHTML学习进度备忘
  8. invoking gdb
  9. Windows2003计划任务设置操作手册
  10. python生成随机二进制文件
  11. linux 第二天
  12. 利用AForge.NET 调用电脑摄像头进行拍照
  13. [Hadoop] - Protocol Buffer安装
  14. 基于C#实现的自动化测试框架:发布自动触发自动化回归测试
  15. python day08 文件操作
  16. yarn查询/cluster/nodes均返回localhost
  17. gtest环境安装
  18. 严重: A child container failed during start的问题解决方法
  19. 『TensorFlow』迁移学习
  20. Ubuntu14.04安装之后的一些配置

热门文章

  1. input check复选框选择后修改&lt;a&gt;标签超链接href
  2. 学习R的悬疑录(不定期更新)
  3. Spring基础15——通过工厂方法来配置bean
  4. Nginx优化_数据包头部信息过大问题
  5. Listview四种视图VIEW
  6. Python核心技术与实战——四|Python黑箱:输入与输出
  7. RabbitMQ发送消息成功,但是接受不到消息
  8. 双层for循环用java中的stream流来实现
  9. 前端之JQuery:JQuery扩展和事件
  10. sys模块-与python解释器交互的模块