反反爬虫,爬虫突破封禁的6种常见方法

1. 构造合理的 HTTP 请求头

除了处理网站表单,requests 模块还是一个设置请求头的利器。HTTP 的请求头是在你每次向网络服务器发送请求时,传递的一组属性和配置信息。HTTP 定义了十几种古怪的请求头类型,不过大多数都不常用。只有下面的七个字段被大多数浏览器用来初始化所有网络请求(表中信息是我自己浏览器的数据)。

 

反反爬虫,爬虫突破封禁的6种常见方法

 

经典的 Python 爬虫在使用 urllib 标准库时,都会发送如下的请求头:

 

反反爬虫,爬虫突破封禁的6种常见方法

 

如果你是一个防范爬虫的网站管理员,你会让哪个请求头访问你的网站呢/p>

 

安装 Requests

 

可在模块的网站上找到下载链接(http://docs.python-requests.org/en/latest/user/install/)和安装方法,或者用任意第三方 Python 模块安装器进行安装。

 

请求头可以通过 requests 模块进行自定义。https://www.whatismybrowser.com/ 网站就是一个非常棒的网站,可以让服务器测试浏览器的属性。我们用下面的程序来采集这个网站的信息,验证我们浏览器的 cookie 设置:

 

反反爬虫,爬虫突破封禁的6种常见方法

 

 

程序输出结果中的请求头应该和程序中设置的 headers 是一样的。

 

虽然网站可能会对 HTTP 请求头的每个属性进行“是否具有人性”的检查,但是我发现通常真正重要的参数就是 User-Agent。无论做什么项目,一定要记得把 User-Agent 属性设置成不容易引起怀疑的内容,不要用 Python-urllib/3.4。另外,如果你正在处理一个警觉性非常高的网站,就要注意那些经常用却很少检查的请求头,比如 Accept-Language 属性,也许它正是那个网站判断你是个人类访问者的关键。

2.   设置合理的cookie 

虽然 cookie 是一把双刃剑,但正确地处理 cookie 可以避免许多采集问题。网站会用 cookie 跟踪你的访问过程,如果发现了爬虫异常行为就会中断你的访问,比如特别快速地填写表单,或者浏览大量页面。虽然这些行为可以通过关闭并重新连接或者改变 IP 地址来伪装,但是如果 cookie 暴露了你的身份,再多努力也是白费。

 

在采集一些网站时 cookie 是不可或缺的。要在一个网站上持续保持登录状态,需要在多个页面中保存一个 cookie。有些网站不要求在每次登录时都获得一个新 cookie,只要保存一个旧的“已登录”的 cookie 就可以访问。

 

如果你在采集一个或者几个目标网站,建议你检查这些网站生成的 cookie,然后想想哪一个 cookie 是爬虫需要处理的。有一些浏览器插件可以为你显示访问网站和离开网站时 cookie 是如何设置的。EditThisCookie(http://www.editthiscookie.com/)是我最喜欢的 Chrome 浏览器插件之一。

 

因为 requests 模块不能执行 JavaScript,所以它不能处理很多新式的跟踪软件生成的 cookie,比如 Google Analytics,只有当客户端脚本执行后才设置 cookie(或者在用户浏览页面时基于网页事件产生 cookie,比如点击按钮)。要处理这些动作,需要用 Selenium 和 PhantomJS 包。

 

Selenium 与 PhantomJS

 

Selenium(http://www.seleniumhq.org/)是一个强大的网络数据采集工具,最初是为网站自动化测试而开发的。近几年,它还被广泛用于获取精确的网站快照,因为它们可以直接运行在浏览器上。Selenium 可以让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。

 

Selenium 自己不带浏览器,它需要与第三方浏览器结合在一起使用。例如,如果你在 Firefox 上运行 Selenium,可以直接看到 Firefox 窗口被打开,进入网站,然后执行你在代码中设置的动作。虽然这样可以看得更清楚,但是我更喜欢让程序在后台运行,所以我 PhantomJS(http://phantomjs.org/download.html)代替真实的浏览器。

 

PhantomJS 是一个“无头”(headless)浏览器。它会把网站加载到内存并执行页面上的 JavaScript,但不会向用户展示网页的图形界面。将 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,可以处理 cookie、JavaScrip、header,以及任何你需要做的事情。

 

可以从PyPI网站(https://pypi.python.org/simple/selenium/)下载Selenium库,也可以用第三方管理器(像pip)用命令行安装。

 

你可以对任意网站(本例用的是 http://pythonscraping.com)调用 webdriver 的 get_cookie()方法来查看 cookie:

 

反反爬虫,爬虫突破封禁的6种常见方法

点击可查看大图

 

这样就可以获得一个非常典型的 Google Analytics 的 cookie 列表:

 

反反爬虫,爬虫突破封禁的6种常见方法

点击可查看大图

 

还可以调用 delete_cookie()、add_cookie() 和 delete_all_cookies() 方法来处理 cookie。另外,还可以保存 cookie 以备其他网络爬虫使用。下面的例子演示了如何把这些函数组合在一起:

 

反反爬虫,爬虫突破封禁的6种常见方法

点击可查看大图

 

在这个例子中,第一个 webdriver 获得了一个网站,打印 cookie 并把它们保存到变量savedCookies 里。第二个 webdriver 加载同一个网站(技术提示:必须首先加载网站,这样 Selenium 才能知道 cookie 属于哪个网站,即使加载网站的行为对我们没任何用处),删除所有的 cookie,然后替换成第一个 webdriver 得到的 cookie。当再次加载这个页面时,两组 cookie 的时间戳、源代码和其他信息应该完全一致。从 Google Analytics 的角度看,第二个 webdriver 现在和第一个 webdriver 完全一样。

3.   爬虫访问速度和路径的控制

有一些防护措施完备的网站可能会阻止你快速地提交表单,或者快速地与网站进行交互。即使没有这些安全措施,用一个比普通人快很多的速度从一个网站下载大量信息也可能让自己被网站封杀。

 

因此,虽然多线程程序可能是一个快速加载页面的好办法——在一个线程中处理数据,另一个线程中加载页面——但是这对编写好的爬虫来说是恐怖的策略。还是应该尽量保证一次加载页面加载且数据请求最小化。如果条件允许,尽量为每个页面访问增加一点儿时间间隔,即使你要增加一行代码:

 

(小编:3 + 随机数 是不是更好一些

 

合理控制速度是你不应该破坏的规则。过度消耗别人的服务器资源会让你置身于非法境地,更严重的是这么做可能会把一个小型网站拖垮甚至下线。拖垮网站是不道德的,是彻头彻尾的错误。所以请控制采集速度!

 

常见表单反爬虫安全措施解密

 

许多像 Litmus 之类的测试工具已经用了很多年了,现在仍用于区分网络爬虫和使用浏览器的人类访问者,这类手段都取得了不同程度的效果。虽然网络机器人下载一些公开的文章和博文并不是什么大事,但是如果网络机器人在你的网站上创造了几千个账号并开始向所有用户发送垃圾邮件,就是一个大问题了。网络表单,尤其是那些用于账号创建和登录的网站,如果被机器人肆意地滥用,网站的安全和流量费用就会面临严重威胁,因此努力限制网站的接入是最符合许多网站所有者的利益的(至少他们这么认为)。

 

这些集中在表单和登录环节上的反机器人安全措施,对网络爬虫来说确实是严重的挑战。

4.   注意网页隐藏的信息

在 HTML 表单中,“隐含”字段可以让字段的值对浏览器可见,但是对用户不可见(除非看网页源代码)。随着越来越多的网站开始用 cookie 存储状态变量来管理用户状态,在找到另一个最佳用途之前,隐含字段主要用于阻止爬虫自动提交表单。

 

下图显示的例子就是 Facebook 登录页面上的隐含字段。虽然表单里只有三个可见字段(username、password 和一个确认按钮),但是在源代码里表单会向服务器传送大量的信息。

 

反反爬虫,爬虫突破封禁的6种常见方法

 

Facebook 登录页面上的隐含字段

 

用隐含字段阻止网络数据采集的方式主要有两种。第一种是表单页面上的一个字段可以用服务器生成的随机变量表示。如果提交时这个值不在表单处理页面上,服务器就有理由认为这个提交不是从原始表单页面上提交的,而是由一个网络机器人直接提交到表单处理页面的。绕开这个问题的最佳方法就是,首先采集表单所在页面上生成的随机变量,然后再提交到表单处理页面。

 

第二种方式是“蜜罐”(honey pot)。如果表单里包含一个具有普通名称的隐含字段(设置蜜罐圈套),比如“用户名”(username)或“邮箱地址”(email address),设计不太好的网络机器人往往不管这个字段是不是对用户可见,直接填写这个字段并向服务器提交,这样就会中服务器的蜜罐圈套。服务器会把所有隐含字段的真实值(或者与表单提交页面的默认值不同的值)都忽略,而且填写隐含字段的访问用户也可能被网站封杀。

 

总之,有时检查表单所在的页面十分必要,看看有没有遗漏或弄错一些服务器预先设定好的隐含字段(蜜罐圈套)。如果你看到一些隐含字段,通常带有较大的随机字符串变量,那么很可能网络服务器会在表单提交的时候检查它们。另外,还有其他一些检查,用来保证这些当前生成的表单变量只被使用一次或是最近生成的(这样可以避免变量被简单地存储到一个程序中反复使用)。

5.   避免进入蜜罐

虽然在进行网络数据采集时用 CSS 属性区分有用信息和无用信息会很容易(比如,通过读取 id和 class 标签获取信息),但这么做有时也会出问题。如果网络表单的一个字段通过 CSS 设置成对用户不可见,那么可以认为普通用户访问网站的时候不能填写这个字段,因为它没有显示在浏览器上。如果这个字段被填写了,就可能是机器人干的,因此这个提交会失效。

 

这种手段不仅可以应用在网站的表单上,还可以应用在链接、图片、文件,以及一些可以被机器人读取,但普通用户在浏览器上却看不到的任何内容上面。访问者如果访问了网站上的一个“隐含”内容,就会触发服务器脚本封杀这个用户的 IP 地址,把这个用户踢出网站,或者采取其他措施禁止这个用户接入网站。实际上,许多商业模式就是在干这些事情。

 

下面的例子所用的网页在 http://pythonscraping.com/pages/itsatrap.html。这个页面包含了两个链接,一个通过 CSS 隐含了,另一个是可见的。另外,页面上还包括两个隐含字段:

 

反反爬虫,爬虫突破封禁的6种常见方法
点击可查看大图

 

这三个元素通过三种不同的方式对用户隐藏:

  • 第一个链接是通过简单的 CSS 属性设置 display:none 进行隐藏

  • 电话号码字段 name="phone" 是一个隐含的输入字段

  • 邮箱地址字段 name="email" 是将元素向右移动 50 000 像素(应该会超出电脑显示器的边界)并隐藏滚动条

 

因为 Selenium 可以获取访问页面的内容,所以它可以区分页面上的可见元素与隐含元素。通过 is_displayed() 可以判断元素在页面上是否可见。

 

例如,下面的代码示例就是获取前面那个页面的内容,然后查找隐含链接和隐含输入字段:

 

反反爬虫,爬虫突破封禁的6种常见方法

点击可查看大图

 

Selenium 抓取出了每个隐含的链接和字段,结果如下所示:

 

反反爬虫,爬虫突破封禁的6种常见方法

点击可查看大图

 

虽然你不太可能会去访问你找到的那些隐含链接,但是在提交前,记得确认一下那些已经在表单中、准备提交的隐含字段的值(或者让 Selenium 为你自动提交)。

6.   使用可变IP

建立网络爬虫的第一原则是:所有信息都可以伪造。你可以用非本人的邮箱发送邮件,通过命令行自动化鼠标的行为,或者通过 IE 5.0 浏览器耗费网站流量来吓唬网管。

 

但是有一件事情是不能作假的,那就是你的 IP 地址。任何人都可以用这个地址给你写信:“美国华盛顿特区宾夕法尼亚大道西北 1600 号,总统,邮编 20500。”但是,如果这封信是从新墨西哥州的阿尔伯克基市发来的,那么你肯定可以确信给你写信的不是美国总统。

来源:夏墨独周

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2017年8月10日
下一篇 2017年8月10日

相关推荐