为何大量网站不能抓取?爬虫突破封禁的6种常见方法
在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长。今天大众好像更倾向于用“网络数据采集”,有时会把网络数据采集程序称为网络机器人(bots)。最常用的方法是写一个自动化程序向网络服务器请求数据(通常是用 HTML 表单或其他网页文件),然后对数据进行解析,提取需要的信息。
本文假定读者已经了解如何用代码来抓取一个远程的 URL,并具备表单如何提交及 JavaScript 在浏览器如何运行的机制。想更多了解网络数据采集基础知识,可以参考文后的资料。
在采集网站的时会遇到一些比数据显示在浏览器上却抓取不出来更令人沮丧的事情。也许是向服务器提交自认为已经处理得很好的表单却被拒绝,也许是自己的 IP 地址不知道什么原因直接被网站封杀,无法继续访问。
原因可能是一些最复杂的 bug,也可能是这些 bug 让人意想不到(程序在一个网站上可以正常使用,但在另一个看起来完全一样的网站上却用不了)。最有可能出现的情况是:对方有意不让爬虫抓取信息。网站已经把你定性为一个网络机器人直接拒绝了,你无法找出原因。
接下来就介绍一些网络采集的黑魔法(HTTP headers、CSS 和 HTML 表单等),以克服网站阻止自动采集。不过,先让我们聊聊道德问题。
网络爬虫的道德与礼仪
说实话,从道德角度讲,写作以下文字不易。我自己的网站被网络机器人、垃圾邮件生成器、网络爬虫和其他各种不受欢迎的虚拟访问者骚扰过很多次了,你的网站可能也一样。既然如此,为什么还要介绍那些更强大的网络机器人呢?有几个很重要的理由。
白帽子工作。在采集那些不想被采集的网站时,其实存在一些非常符合道德和法律规范的理由。比如我之前的工作就是做网络爬虫,我曾做过一个自动信息收集器,从未经许可的网站上自动收集客户的名称、地址、电话号码和其他个人信息,然后把采集的信息提交到网站上,让服务器删除这些客户信息。为了避免竞争,这些网站都会对网络爬虫严防死守。但是,我的工作要确保公司的客户们都匿名(这些人都是家庭暴力受害者,或者因其他正当理由想保持低调的人),这为网络数据采集工作创造了极其合理的条件,我很高兴自己有能力从事这项工作。
虽然不太可能建立一个完全“防爬虫”的网站(最起码得让合法的用户可以方便地访问网站),但我还是希望以下内容可以帮助人们保护自己的网站不被恶意攻击。下文将指出每一种网络数据采集技术的缺点,你可以利用这些缺点保护自己的网站。其实,大多数网络机器人一开始都只能做一些宽泛的信息和漏洞扫描,接下来介绍的几个简单技术就可以挡住 99% 的机器人。但是,它们进化的速度非常快,最好时刻准备迎接新的攻击。
和大多数程序员一样,我从来不相信禁止某一类信息的传播就可以让世界变得更和谐。
阅读之前,请牢记:这里演示的许多程序和介绍的技术都不应该在网站上使用。
爬虫黑科技:
网络机器人看起来像人类用户的一些方法
网站防采集的前提就是要正确地区分人类访问用户和网络机器人。虽然网站可以使用很多识别技术(比如验证码)来防止爬虫,但还是有一些十分简单的方法,可以让你的网络机器人看起来更像人类访问用户。
1. 构造合理的 HTTP 请求头
除了处理网站表单,requests 模块还是一个设置请求头的利器。HTTP 的请求头是在你每次向网络服务器发送请求时,传递的一组属性和配置信息。HTTP 定义了十几种古怪的请求头类型,不过大多数都不常用。只有下面的七个字段被大多数浏览器用来初始化所有网络请求(表中信息是我自己浏览器的数据)。
经典的 Python 爬虫在使用 urllib 标准库时,都会发送如下的请求头:
如果你是一个防范爬虫的网站管理员,你会让哪个请求头访问你的网站呢?
安装 Requests
可在模块的网站上找到下载链接(http://docs.python-requests.org/en/latest/user/install/)和安装方法,或者用任意第三方 Python 模块安装器进行安装。
请求头可以通过 requests 模块进行自定义。https://www.whatismybrowser.com/ 网站就是一个非常棒的网站,可以让服务器测试浏览器的属性。我们用下面的程序来采集这个网站的信息,验证我们浏览器的 cookie 设置:
程序输出结果中的请求头应该和程序中设置的 headers 是一样的。
虽然网站可能会对 HTTP 请求头的每个属性进行“是否具有人性”的检查,但是我发现通常真正重要的参数就是 User-Agent。无论做什么项目,一定要记得把 User-Agent 属性设置成不容易引起怀疑的内容,不要用 Python-url