网络爬虫突破限制的常见方法

在互联网上爬取数据的过程中难免出现ip被封或者服务器返回403等等,这可能是你被网站检测为爬虫而采取的反爬措施,本文主要总结了一些常见的情况及规避的措施。

推荐理由:

本文总结了大多数网站常用的禁止网络爬虫的技术手段,并针对这些问题提供了详细的解决思路和解决方法,采取这些措施可以绕过绝大多数爬虫相关技术限制,从而采集到期望的数据信息,希望本文对大家有所帮助.

推荐星级:★★★

网络爬虫,是一种自动获取网页内容的程序,它存在的时间差不多和互联网存在的时间一样长。然而互联网上大量的爬虫也给网站带来了很大的困扰,严重影响了网站的正常运行,甚至威胁到数据及系统的安全,于是各式各样的反爬虫技术应运而生。在程序员的互相博弈之下,两种技术都得到了极大的发展,比如12306的验证码发展史,就是一场经典的反爬虫技术发展史,以至于12306从最初特别简单的验证码发展到如今令人发指的验证码。

在做网络爬虫时,经常可能会遇到数据显示在浏览器上但却抓取不出来,也许是向服务器提交自认为已经处理得很好的表单却被拒绝,也许是自己的账号或者IP地址不知道什么原因直接被网站封杀,无法继续访问。此时,最可能出现的情况是:对方使用了反爬虫技术,有意不让爬虫抓取信息。接下来本文就介绍一些常见的克服网站阻止自动采集的方法来突破这些限制。

1.构造合理的 HTTP 请求头

HTTP 的请求头是在你每次向网络服务器发送请求时,传递的一组属性和配置信息。HTTP 定义了十几种古怪的请求头类型,不过大多数都不常用。只有下面的七个字段被大多数浏览器用来初始化所有网络请求。

虽然网站可能会对HTTP请求头的每个属性都进行检查,但是通常真正重要的参数就是User-Agent。无论是什么样的爬虫,一定要记得把User-Agent属性设置成不容易引起怀疑的内容,比如如果你用python的urllib标准库时,它的User-Agent可能就会是Python-urllib/3.4,这样就很容易被禁。另外,如果你正在处理一个警觉性非常高的网站,就要注意那些经常用却很少检查的请求头,比如 Accept-Language属性,也许它正是那个网站判断你是否是人类访问者的关键。还有一部分网站会对Referer进行检测,比如一些资源网站的防盗链就是检测Referer。如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。
另外,请求头还可能让网站改变内容的布局样式。例如,用移动设备浏览网站时,通常会看到一个没有广告、Flash以及其他干扰的简化的网站版本。因此,把你的请求头User-Agent改成下面这样,也许就可以看到一个更容易采集的网站了。
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) App leWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53

2.设置cookie

cookie其实是储存在用户终端的一些被加密的数据,有些网站通过cookies来识别用户身份,如果某个访问总是高频率地发请求,很可能会被网站注意到,被怀疑为爬虫,这时网站就可以通过cookie找到这个访问的用户而拒绝其访问。对于这种情况可以通过禁用cookie,主动阻止服务器写入。禁用cookie可以防止使用cookies识别爬虫的网站来禁掉我们。
但是采集某些网站时cookie是不可或缺的。要在一个网站上持续保持登录状态,需要在多个页面中保存一个cookie。有些网站不要求在每次登录时都获得一个新cookie,只要保存一个旧的已登录的 cookie 就可以访问。

3.降低访问频率

为了提高爬虫的效率,很多人在爬虫中使用多线程、异步等手段,使得爬虫在一个小时内甚至可以访问数十万次页面,给服务器带来了不小的压力,因此有一些防护措施较完备的网站就可能会阻止你快速地提交表单,或者快速地与网站进行交互。即使没有这些安全措施,用一个比普通人快很多的速度从一个网站下载大量信息也可能让自己被网站封杀。
遇到这种网站,如果你对爬虫效率要求不高,可以尝试降低爬虫访问速度,比如不再使用多线程技术,每次访问后设置等待时间,限制每小时访问量等。比如在python中:

1
2
import time,random#导入包
time.sleep(random.randint(1,9))#设置时间间隔为随机几秒钟

但如果你对爬虫效率要求比较高,每次访问都等待无法满足要求,那么首先需要确定网站是根据什么条件进行限制的,再想办法去突破限制。比如很多网站都是通过IP来限制访问量的,那么就可以使用代理IP,每请求几次就换一个IP,这样就可以避免被禁了。

4.动态页面的反爬虫

上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过ajax请求得到,或者通过JavaScript生成的。对于这种情况,我们首先需要对网络请求进行分析,如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接模拟ajax请求,对响应的json进行分析得到需要的数据。
如果这种方法不行,或者需要处理JS,那么则可以采用selenium+phantomJS。PhantomJS是一个无界面的WebKit浏览器,除了没有界面,基本和一般的浏览器一样。Selenium是一个自动化测试工具,它可以驱动浏览器,两者结合,双剑合璧,从填写表单到点击按钮再到滚动页面,全部都可以模拟,不考虑具体的请求和响应过程,只是完完整整的把人浏览页面获取数据的过程模拟一遍。 用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据(上述的通过添加Headers一定程度上就是为了伪装成浏览器),phantomJS本身就是一个没有界面的浏览器,只是操控这个浏览器的不是人而是程序。利用selenium+phantomJS能干很多事情,cookie、JavaScript、header都能自动处理,比如现在比较流行的滑动式验证码,就可以使用它们解决。

5.注意隐含输入字段值

为了反爬虫,一些网站会在html表单中故意添加隐藏元素,这些隐含字段可以让字段的值对浏览器可见,但是对用户不可见,除非看网页源代码。如果你爬着爬着就把隐藏元素都爬出来了,那么就很容易被网站识别出来,只要被网站发现,就有可能立马被封账号或者IP,所以在提交表单前一定要先看一下元素再进行爬取。
比如下面这段html代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><head>
<title>A bot-proof form</title>
<style>
body {overflow-x: hidden;}
.customHidden {
position: absolute;
right: 50000px;
}
</style>
<style type="text/css"></style>
</head>
<body>
<h2>A bot-proof form</h2>
<a href="http://pythonscraping.com/dontgohere" style="display:none;">Go here!</a>
<a href="http://pythonscraping.com">Click me!</a>
<form>
<input type="hidden" name="phone" value="valueShouldNotBeModified">
<p><input type="text" name="email" class="customHidden" value="intentionallyBlank"></p>
<p><input type="text" name="firstName"></p>
<p><input type="text" name="lastName"></p>
<p><input type="submit" value="Submit"></p>
</form>
</body></html>

这段代码包含了两个链接,但是其中一个通过css隐藏了,一旦你访问了这个链接,可能就会中招。而在表单中,电话号码字段name=”phone”是一个隐含的输入字段,邮箱地址字段name=”email”是将元素向右移动50000像素并隐藏滚动条,这两个对用户而言都是不可见的。
处理这种页面可以在访问前先进行分析,也可以使用Selenium,通过is_displayed来判断元素在页面上是否可见,从而避免被封禁。

6.使用代理

网络爬虫几乎所有的数据都是伪造的,但是有一项却是不能作假的,那就是IP地址。因此很多网站为了防爬虫,制定了一系列规则去封杀IP,简单粗暴又十分有效。如果你的IP地址被封,那么这时就该代理上场了。所谓代理就是介于用户与网站之间的第三者:用户先将请求发到代理,然后代理再发到服务器,这样看起来就像是代理在访问那个网站了。这时,服务器会将这次访问算到代理头上。同时用多个代理的话,单个IP的访问量就降下去了,于是就有可能逃过一劫。
python中的requests使用代理非常简单:

1
2
3
4
5
import requests
proxies = {
"http": "XXX.XX.XX.XX:XX",
}
print requests.get('http://www.ip181.com/',proxies=proxies).content

http://www.ip181.com是一个可以检测代理IP的网站,它可以检测出你使用的ip是什么,正好可以用来检验自己是否使用代理ip成功。
如果你有多个代理IP,那么可以建立一个IP池,每次随机从IP池中选择一个进行访问,如果访问失败了,则将其从池中去除即可。

以上就是一些防止爬虫被封禁的常见情况和解决办法。总之,反爬虫的技术总是想方设法地去区分人和程序,所以防止被封禁的核心思想就是尽量伪装成正常的用户,只要按着这个思想走,总能找到具体的方法。

http://www.toutiao.com/a6289159538663538946/
http://www.jianshu.com/p/73697828b8f8
http://blog.163.com/zhuyunyun_work/blog/static/19611284020142594424758/
http://www.cnblogs.com/ShakeTian/articles/5957482.html
https://zhuanlan.zhihu.com/p/20520370?columnSlug=python-hacker