以下记录自己在用C#语言,实现网页内容抓取,模拟登陆网页等过程中,所从无到有,一点点知道的一些知识,记录下来,以供参考(高手不要笑哈):
1.Host不是自己指定/设置的,而是http请求会自动去设置
用C#写http请求的header中,开始以为Host也是自己设置的:
req.Headers.Add(“Host”, “login.live.com”);
结果发现无法设置,会出错。
后来才知道,此Host值,是不需要程序操作,而是http的库会自动设置的。
2.POST类型请求,除了填写数据,还要设置ContentType 为application/x-www-form-urlencoded
如果是POST类型的http请求,那么除了要提交对应的数据之外,还要设置对应的ContentType:
req.ContentType = “application/x-www-form-urlencoded”;
其中提交的数据,是quote编码后的。
3.User-Agent很重要
在提交http请求的时候,User-Agent在很多时候,都很重要。至少我知道的有这些情况:
(1)用于识别不同浏览器,以实现不同的行为
看到关于User-Agent的解释:
http://baike.baidu.com/view/3398471.htm
中介绍的,可能会有网页代码实现,会考虑到识别对应的User-Agent,以得知当前所用浏览器类型,然后肯能会针对不同浏览器,有不同的行为或者网页内容呈现。
(2)C#中http的response中的header中的Set-Cookie有误
之前遇到过,User-Agent设置为:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
结果http返回的response中的cookies,即resp.Cookies,就是错误的(注:该cookies是.NET(C#)库所解析出来的)
而用其他一些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; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E
就可以得到正确的resp.Cookies就是正确的。
所以,肯能有时候会遇到,不同的User-Agent,会导致一些莫名其妙的事情,比如这里可能会导致.NET的解析Set-Cookie的bug出现和不出现。
关于该问题的详情去看这里:
【经验记录】C#中,库函数有bug,会将http所返回的response响应中的headers头信息中的Set-Cookie值,解析错误,丢失部分cookie
4.Accept-Encoding设置为gzip,deflate会导致返回的html网页是乱码
具体详情和解释,去看这里:
【已解决】设置Accept-Encoding为gzip,deflate,返回的网页是乱码
5.可以通过关闭“自动运行重定向”,以获取重定向中所返回的cookie值
想要获得对应的网页重定向过程中,所返回的cookie,即
访问地址A,结果内部过程是,服务器收到A地址请求,其返回内容中包括了cookie,但是由于此A是重定向,导致最终我们所获得的网页内容是重定向之后的B地址的内容,而且对应的cookie,也是B地址的cookie,而无法获得重定向之前A地址所返回的cookie,所以,想要获得A地址的cookie,即重定向过程中的cookie值,
对于C#代码,可以通过
req.AllowAutoRedirect = false;
这样就可以禁止重定向,可以获得我们所需要的cookie了。
然后再手动去再次提交http请求去访问B地址,即可完整模拟整个重定向的过程。
更加详细的解释去看这里:
6.分析网页执行过程,目前已经好用的工具有IE9的F12和Chrome的”开发人员工具”
具体用法和功能特点比较,参见:
【总结】浏览器中的开发人员工具(IE9的F12和Chrome的Ctrl+Shift+I)-网页分析的利器
另外听说对于FireFox下面,也有分析网页的工具:
FireBug + Web Developer
有机会也去试试。
6.如果模拟网页登陆,那么很可能要用到对应的cookie,其中包含了认证的信息
如果模拟网站登陆,那么基本逻辑都是,填写了用户名和密码,以及相关数据,编码后,然后用POST方法提交请求,服务器返回的认证信息,一般都包含在对应的cookie中,所以,如果管理和分析cookie,就很重要。
(1)关于如果访问网页,可以参考这里:
Retrieving HTTP content in .NET
http://www.west-wind.com/presentations/dotnetWebRequest/dotnetWebRequest.htm
其中就有关于cookie的管理功能,如何提交POST数据。
(2)然后我参考其代码,也实现了对应的一些函数,感兴趣的可以去这里看代码:
(3)关于cookie的知识,去看wiki:
http://en.wikipedia.org/wiki/HTTP_cookie
7.C#中,如果cookie的Domain为空,那么会导致HttpWebRequest的CookieContainer.Add死掉
在用C#实现模拟登陆网站的调试过程中,遇到了很多次,都是不小心,将对应的domain为空的cookie,添加到了CookieContainer中,比如这样的代码:
req.CookieContainer.Add(skydriveCookies);
其中skydriveCookies是CookieCollection类型,其中某个cookie的Domain为空,则此行代码一运行,就死掉了,也没有报任何错误,在这点上,VS2010做得很是不好,也没有任何提示。
而最后还是N次的调试,比较,排除,最后才确定代码死掉的原因,是某个Cookie的Domain为空,所导致的。
所以,千万千万要注意,在获得resp.Cookies或者是解析出来的Cookie的话,一定要保证Domain不为空,然后调用CookieContainer.Add才能保证不会死掉。