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

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

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

4. 注意隐含输入字段值

 

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

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

 

 

Facebook 登录页面上的隐含字段

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

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

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

5. 爬虫通常如何避开蜜罐

 

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

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

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

 


点击可查看大图

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

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

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

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

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

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

 

点击可查看大图

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

 

点击可查看大图

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

使用远程服务器来避免 IP 封锁

 

启用远程平台的人通常有两个目的:对更大计算能力和灵活性的需求,以及对可变 IP 地址的需求

6. 使用可变的远程 IP 地址

 

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

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

从技术上说,IP 地址是可以通过发送数据包进行伪装的,就是分布式拒绝服务攻击技术(Distributed Denial of Service,DDoS),攻击者不需要关心接收的数据包(这样发送请求的时候就可以使用假 IP 地址)。但是网络数据采集是一种需要关心服务器响应的行为,所以我们认为 IP 地址是不能造假的。

阻止网站被采集的注意力主要集中在识别人类与机器人的行为差异上面。封杀 IP 地址这种矫枉过正的行为,就好像是农民不靠喷农药给庄稼杀虫,而是直接用火烧彻底解决问题。它是最后一步棋,不过是一种非常有效的方法,只要忽略危险 IP 地址发来的数据包就可以了。但是,使用这种方法会遇到以下几个问题。

  • IP 地址访问列表很难维护。虽然大多数大型网站都会用自己的程序自动管理 IP 地址访问列表(机器人封杀机器人),但是至少需要人偶尔检查一下列表,或者至少要监控问题的增长。

  • 因为服务器需要根据 IP 地址访问列表去检查每个准备接收的数据包,所以检查接收数据包时会额外增加一些处理时间。多个 IP 地址乘以海量的数据包更会使检查时间指数级增长。为了降低处理时间和处理复杂度,管理员通常会对 IP 地址进行分组管理并制定相应的规则,比如如果这组 IP 中有一些危险分子就“把这个区间的所有 256 个地址全部封杀”。于是产生了下一个问题。

  • 封杀 IP 地址可能会导致意外后果。例如,当我还在美国麻省欧林工程学院读本科的时候,有个同学写了一个可以在 http://digg.com/ 网站(在 Reddit 流行之前大家都用 Digg)上对热门内容进行投票的软件。这个软件的服务器 IP 地址被 Digg 封杀,导致整个网站都不能访问。于是这个同学就把软件移到了另一个服务器上,而 Digg 自己却失去了许多主要目标用户的访问量。

虽然有这些缺点,但封杀 IP 地址依然是一种十分常用的手段,服务器管理员用它来阻止可疑的网络爬虫入侵服务器。

 

Tor 代理服务器

洋葱路由(The Onion Router)网络,常用缩写为 Tor,是一种 IP 地址匿名手段。由网络志愿者服务器构建的洋葱路由器网络,通过不同服务器构成多个层(就像洋葱)把客户端包在最里面。数据进入网络之前会被加密,因此任何服务器都不能偷取通信数据。另外,虽然每一个服务器的入站和出站通信都可以被查到,但是要想查出通信的真正起点和终点,必须知道整个通信链路上所有服务器的入站和出站通信细节,而这基本是不可能实现的。

 Tor 匿名的局限性

虽然我们在本文中用 Tor 的目的是改变 IP 地址,而不是实现完全匿名,但有必要关注一下 Tor 匿名方法的能力和不足。

虽然 Tor 网络可以让你访问网站时显示的 IP 地址是一个不能跟踪到你的 IP 地址,但是你在网站上留给服务器的任何信息都会暴露你的身份。例如,你登录 Gmail 账号后再用 Google 搜索,那些搜索历史就会和你的身份绑定在一起。

另外,登录 Tor 的行为也可能让你的匿名状态处于危险之中。2013 年 12 月,一个哈佛大学本科生想逃避期末考试,就用一个匿名邮箱账号通过 Tor 网络给学校发了一封炸弹威胁信。结果哈佛大学的 IT 部门通过日志查到,在炸弹威胁信发来的时候,Tor 网络的流量只来自一台机器,而且是一个在校学生注册的。虽然他们不能确定流量的最初源头(只知道是通过 Tor 发送的),但是作案时间和注册信息证据充分,而且那个时间段内只有一台机器是登录状态,这就有充分理由起诉那个学生了。

登录 Tor 网络不是一个自动的匿名措施,也不能让你进入互联网上任何区域。虽然它是一个实用的工具,但是用它的时候一定要谨慎、清醒,并且遵守道德规范。

在 Python 里使用 Tor,需要先安装运行 Tor,下一节将介绍。Tor 服务很容易安装和开启。只要去 Tor 下载页面下载并安装,打开后连接就可以。不过要注意,当你用 Tor 的时候网速会变慢。这是因为代理有可能要先在全世界网络上转几次才到目的地!

 

PySocks

PySocks 是一个非常简单的 Python 代理服务器通信模块,它可以和 Tor 配合使用。你可以从它的网站(https://pypi.python.org/pypi/PySocks)上下载,或者使用任何第三方模块管理器安装。

这个模块的用法很简单。示例代码如下所示。运行的时候,Tor 服务必须运行在 9150 端口(默认值)上:

 

网站 http://icanhazip.com/ 会显示客户端连接的网站服务器的 IP 地址,可以用来测试 Tor 是否正常运行。当程序执行之后,显示的 IP 地址就不是你原来的 IP 了。

如果你想在 Tor 里面用 Selenium 和 PhantomJS,不需要 PySocks,只要保证 Tor 在运行,然后增加 service_args 参数设置代理端口,让 Selenium 通过端口 9150 连接网站就可以了:

 

和之前一样,这个程序打印的 IP 地址也不是你原来的,而是你通过 Tor 客户端获得的 IP 地址。

从网站主机运行

如果你拥有个人网站或公司网站,那么你可能已经知道如何使用外部服务器运行你的网络爬虫了。即使是一些相对封闭的网络服务器,没有可用的命令行接入方式,你也可以通过网页界面对程序进行控制。

如果你的网站部署在 Linux 服务器上,应该已经运行了 Python。如果你用的是 Windows 服务器,可能就没那么幸运了;你需要仔细检查一下 Python 有没有安装,或者问问网管可不可以安装。

大多数小型网络主机都会提供一个软件叫 cPanel,提供网站管理和后台服务的基本管理功能和信息。如果你接入了 cPanel,就可以设置 Python 在服务器上运行——进入“Apache Handlers”然后增加一个 handler(如还没有的话):

 

这会告诉服务器所有的 Python 脚本都将作为一个 CGI 脚本运行。CGI 就是通用网关接口(Common Gateway Interface),是可以在服务器上运行的任何程序,会动态地生成内容并显示在网站上。把 Python 脚本显式地定义成 CGI 脚本,就是给服务器权限去执行 Python 脚本,而不只是在浏览器上显示它们或者让用户下载它们。

写完 Python 脚本后上传到服务器,然后把文件权限设置成 755,让它可执行。通过浏览器找到程序上传的位置(也可以写一个爬虫来自动做这件事情)就可以执行程序。如果你担心在公共领域执行脚本不安全,可以采取以下两种方法。

  • 把脚本存储在一个隐晦或深层的 URL 里,确保其他 URL 链接都不能接入这个脚本,这样可以避免搜索引擎发现它。

  • 用密码保护脚本,或者在执行脚本之前用密码或加密令牌进行确认。

确实,通过这些原本主要是用来显示网站的服务运行 Python 脚本有点儿复杂。比如,你可能会发现网络爬虫运行时网站的加载速度变慢了。其实,在整个采集任务完成之前页面都是不会加载的(得等到所有“print”语句的输出内容都显示完)。这可能会消耗几分钟,几小时,甚至永远也完成不了,要看程序的具体情况了。虽然它最终一定能完成任务,但是可能你还想看到实时的结果,这样就需要一台真正的服务器了。

 

从云主机运行

虽然云计算的花费可能是无底洞,但是写这篇文章时,启动一个计算实例最便宜只要每小时 1.3 美分(亚马逊 EC2 的 micro 实例,其他实例会更贵),Google 最便宜的计算实例是每小时 4.5 美分,最少需要用 10 分钟。考虑计算能力的规模效应,从大公司买一个小型的云计算实例的费用,和自己买一台专业实体机的费用应该差不多——不过用云计算不需要雇人去维护设备。

设置好计算实例之后,你就有了新 IP 地址、用户名,以及可以通过 SSH 进行实例连接的公私密钥了。后面要做的每件事情,都应该和你在实体服务器上干的事情一样了——当然,你不需要再担心硬件维护,也不用运行复杂多余的监控工具了。

总结

爬虫被封禁常见原因列表

 

如果你一直被网站封杀却找不到原因,那么这里有个检查列表,可以帮你诊断一下问题出在哪里。

    • 首先,检查 JavaScript 。如果你从网络服务器收到的页面是空白的,缺少信息,或其遇到他不符合你预期的情况(或者不是你在浏览器上看到的内容),有可能是因为网站创建页面的 JavaScript 执行有问题

    • 检查正常浏览器提交的参数。如果你准备向网站提交表单或发出 POST 请求,记得检查一下页面的内容,看看你想提交的每个字段是不是都已经填好,而且格式也正确。用 Chrome 浏览器的网络面板(快捷键 F12 打开开发者控制台,然后点击“Network”即可看到)查看发送到网站的 POST 命令,确认你的每个参数都是正确的。

    • 是否有合法的 Cookie?如果你已经登录网站却不能保持登录状态,或者网站上出现了其他的“登录状态”异常,请检查你的 cookie。确认在加载每个页面时 cookie 都被正确调用,而且你的 cookie 在每次发起请求时都发送到了网站上。

    • IP 被封禁?如果你在客户端遇到了 HTTP 错误,尤其是 403 禁止访问错误,这可能说明网站已经把你的 IP 当作机器人了,不再接受你的任何请求。你要么等待你的 IP 地址从网站黑名单里移除,要么就换个 IP 地址(可以去星巴克上网)。如果你确定自己并没有被封杀,那么再检查下面的内容。

      • 确认你的爬虫在网站上的速度不是特别快。快速采集是一种恶习,会对网管的服务器造成沉重的负担,还会让你陷入违法境地,也是 IP 被网站列入黑名单的首要原因。给你的爬虫增加延迟,让它们在夜深人静的时候运行。切记:匆匆忙忙写程序或收集数据都是拙劣项目管理的表现;应该提前做好计划,避免临阵慌乱。

      • 还有一件必须做的事情:修改你的请求头!有些网站会封杀任何声称自己是爬虫的访问者。如果你不确定请求头的值怎样才算合适,就用你自己浏览器的请求头吧。

      • 确认你没有点击或访问任何人类用户通常不能点击或接入的信息。

      • 如果你用了一大堆复杂的手段才接入网站,考虑联系一下网管吧,告诉他们你的目的。试试发邮件到 webmaster@< 域名 > 或 admin@< 域名 >,请求网管允许你使用爬虫采集数据。管理员也是人嘛!

猜你喜欢

转载自www.cnblogs.com/changkuk/p/10012547.html