为何大量网站不能抓取?爬虫突破封禁的6种常见方法( 二 )


虽然网站可能会对 HTTP 请求头的每个属性进行“是否具有人性”的检查,但是我发现通常真正重要的参数就是 User-Agent 。无论做什么项目,一定要记得把 User-Agent 属性设置成不容易引起怀疑的内容,不要用 Python-urllib/3.4 。另外,如果你正在处理一个警觉性非常高的网站,就要注意那些经常用却很少检查的请求头,比如 Accept-Language 属性,也许它正是那个网站判断你是个人类访问者的关键 。
请求头会改变你观看网络世界的方式
假设你想为一个机器学习的研究项目写一个语言翻译机,却没有大量的翻译文本来测试它的效果 。很多大型网站都会为同样的内容提供不同的语言翻译,根据请求头的参数响应网站不同的语言版本 。因此,你只要简单地把请求头属性从 Accept-Language:en-US 修改成 Accept-Language:fr,就可以从网站上获得“Bonjour”(法语,你好)这些数据来改善翻译机的翻译效果了(大型跨国企业通常都是好的采集对象) 。
请求头还可以让网站改变内容的布局样式 。例如,用移动设备浏览网站时,通常会看到一个没有广告、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 是一把双刃剑,但正确地处理 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:
点击可查看大图
这样就可以获得一个非常典型的 Google Analytics 的 cookie 列表:
点击可查看大图
还可以调用 delete_cookie()、add_cookie() 和 delete_all_cookies() 方法来处理 cookie 。另外,还可以保存 cookie 以备其他网络爬虫使用 。下面的例子演示了如何把这些函数组合在一起:
点击可查看大图
在这个例子中,第一个 webdriver 获得了一个网站,打印 cookie 并把它们保存到变量savedCookies 里 。第二个 webdriver 加载同一个网站(技术提示:必须首先加载网站,这样 Selenium 才能知道 cookie 属于哪个网站,即使加载网站的行为对我们没任何用处),删除所有的 cookie,然后替换成第一个 webdriver 得到的 cookie 。当再次加载这个页面时,两组 cookie 的时间戳、源代码和其他信息应该完全一致 。从 Google Analytics 的角度看,第二个 webdriver 现在和第一个 webdriver 完全一样 。


推荐阅读