一、User-Agent字段
在上一节课我们只讲述了一个头部字段Content-Type,今天我们拿两个常用的字段User-Agent和Referer字段,我们一个个的来演示,先说User-Agent吧,首先我们来看一看两个图片,第一个是抓取c++程序发出的数据包,如下:
第二个是通过抓取浏览器网页表单提交数据的数据包:
大家有没有发现两个数据包里的User-Agent值是不一样的,c++程序使用的是winHttpRequest组件,而它的User-Agent里的值却含有“WinHttp.WinHttpRequest.5”字样,浏览器发送的数据包却是含有“AppleWebKit”、“Chrome”、Safari这种字样的,一看就知道一个是浏览器的,一个是程序的。如果此时web后台服务端防护机制比较好,对这种网络爬虫进行阻止拦截,那我们的程序不就没有用了吗?所谓道高一尺魔高一丈,我们来演示这种机制,只需要在后台PHP程序里添加一点代码进行判断,完整代码如下:
?php
$name=$_POST[name];
$pass=$_POST[pass];
$userAgent=$_SERVER[HTTP_USER_AGENT];
$arr=explode(WinHttp,$userAgent);
print_r($arr);
if(count($arr)1){
return;
}
echo$name./br;
echo$pass./br;
?
里面的explode(WinHttp,$userAgent);用来按照指定字符串分割另外一个字符串的,这里用WinHttp作为分隔符,来分割$userAgent这个字符串变量,而print_r($arr);用来打印分割的结果。现在我们用c++程序再来测试一下,并且用Fiddler抓包看看,如图:
分隔成3个部分,print_r($arr)也打印出来了分隔结果,分隔之后后面提交的用户名和密码并没有打印输出,而是return返回了,并不能正常提交数据了。那我们c++程序如何应对呢?这就是头部字段的重要性,我们只需要发送数据之前,先把头设置一下就可以了,设置成浏览器里抓取的值:
“Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/.36(KHTML,likeGecko)Chrome/63.0..Safari/.36”,c++代码演示如下:
hr=pRequest-SetRequestHeader(_T(User-Agent),_T(Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/.36(KHTML,likeGecko)Chrome/63.0..Safari/.36));
在原有的基础上加上上面一句就OK了,再次抓包分析看看:
是不是数据提交成功了,User-Agent的值跟浏览器里的一模一样,这就是伪造请求头部字段。
二、Referer字段
说完了User-Agent字段,该说Referer字段了,Referer翻译成中文是引用的意思,引用了哪个页面?比如说一个注册页面A,当你填写好内容点击提交按钮的时候就会跳转到B页面,这是A页面就是B的引用页面,换句话说就是当前页面是从哪里过来的?如果我们编写程序直接提交数据到B页面,并没有经过A页面,那么这时候B页面要是检测这个Referer字段,发现没有,它会阻止你提交数据,这样一来你就会提交数据失败。我们再次演示,改动一下PHP网页程序,如下:
?php
$name=$_POST[name];
$pass=$_POST[pass];
$userAgent=$_SERVER[HTTP_USER_AGENT];
$referer=$_SERVER[HTTP_REFERER];
$arr=explode(WinHttp,$userAgent);
print_r($arr);
if(count($arr)1){
return;
}
if($referer!=