从本质上来讲,阻止Web 爬虫就意味着你需要让脚本和机器难以从你的网站上获取它们所需的数据,但不能让那些真正的用户和搜索引擎爬取数据变得困难。
然而不幸的是,要做到这一点很难,你需要在防止Web 爬虫和降级真实用户和搜索引擎的可访问性之间进行权衡。
为了阻止Web 爬虫(也称为Webscraping,Screenscraping,Web数据挖掘,Web收集或Web数据提取),你需要了解这些爬虫的工作原理,以及它们为什么能够运行良好的原因,本文的内容将会告诉你阻止爬虫爬取数据的答案。
一般来说,这些爬虫程序是为了从你的网站提取特定的信息,如文章,搜索结果,产品详细信息,或你的案例中爬取艺术家和专辑等信息。通常,人们使用爬虫爬取特定的数据的目的是将这些数据在自己的网站上进行重用(并从你的内容中赚自己的钱),或为你的网站(如移动应用程序)构建一种“假冒的”替代方案,甚至用于私人研究或分析目的。
基本上,网络中存在着各种类型的爬虫,每一种爬虫的工作方式都不尽相同:
· 蜘蛛(Spider),例如谷歌的机器人或网站复制工具,比如HTTrack,这中爬虫会访问你的网站,并递归地跟随到其他页面的链接,以获取数据。这些爬虫有时用于定向的爬取来获取特定的数据,通常与HTML解析器结合,然后从每个页面中提取所需要的数据。
· Shell脚本:有时候,常用的Unix工具也用于爬取数据,例如:使用shell脚本执行Wget或Curl下载Web页面,通常再结合Grep(使用正则表达式)提取所需的数据。这些是最简单的爬虫,也是最脆弱的一种爬虫(不要尝试使用正则表达式解析HTML!)。
· HTML爬虫和解析器,例如基于Jsoup,Scrapy等等的爬虫技术。这类爬虫有点类似于基于shell脚本的正则表达式的爬虫,都是通过基于在HTML中进行正则匹配提取你的页面中的数据,并忽略其他的内容。
所以,如果你的网站具有搜索功能,那么这样的爬虫可能会提交一个搜索的HTTP请求,然后从结果页的HTML中获取所有结果的链接及其标题,有时候会发起请求数百次和数百种不同的搜索行为,以便专门获取搜索结果链接和网页标题。这些爬虫是最常见的一种。
· 屏幕爬虫,这类爬虫是基于例如 Selenium或PhantomJS编写的。实际上这种爬虫是在真正的浏览器中打开了你的网站,并运行JavaScript,AJAX等等,然后再从网页中获取所需的文本,一般的做法如下:
o 在页面加载和JavaScript运行之后,从浏览器中获取HTML,然后使用HTML解析器来提取所需的数据或文本。这些是最常见的爬取数据的手法,这些方法在HTML解析器和其他的爬虫方法不能用的情况下也有效。
o 对渲染页面进行屏幕截图,然后使用OCR技术从屏幕截图中提取所需的文本。这中方法比较罕见,只有在爬取数据没有办法的情况下才会使用这种专用的爬虫。
基于浏览器的屏幕爬虫更难处理,因为它们运行脚本,渲染HTML,并且可以像一个真正的人在浏览你的网站一样。
· 在线的Web爬虫服务,如ScrapingHub或Kimono。事实上,有些人的工作就是弄清楚如何抓取你的网站的数据,并提出内容给别人使用。这类爬虫技术,有时候会使用庞大的代理网络和不断变化的IP地址来突破限制和阻止,所以它们是问题比较严重的一类爬虫。
专业的爬虫服务是最难以阻止的,这不需要感到奇怪,但是如果你弄清楚Web 爬虫是如何爬取你的网站的,那么这些爬虫(以及为这类爬虫服务付款方式的人)可能不会因为你的网站的数据而遭到困扰了。
· 将你的网站使用框架嵌入其他网站的网页中,并将你的网站嵌入到移动应用中。
虽然在技术上来说这种手法不算是爬虫,但这的确也算是一个问题,因为移动应用程序(Android和iOS)可以嵌入你的网站,甚至注入自定义的CSS和JavaScript,从而完全改变你的网站的外观,并且只显示所需的信息,如文章内容本身或搜索结果列表,以及隐藏一些东西,如页眉,页脚或广告。
· 人工复制和粘贴:网站访客会复制和粘贴你的网站的内容,以便在其他地方使用。不幸的是,要阻止这种方法你基本上无能为力。
这些不同类型的爬虫之间存在很多重叠的地方,即使使用不同的技术和方法来获取你的内容,许多爬虫也将表现出相似的行为。
以上这些提示信息大部分是我自己的想法,包括我在编写爬虫时遇到的各种困难,以及来自互联网上的一些信息和想法。
如何阻止爬虫
一些检测和阻止爬虫的常见方法:
监控你的日志和流量模式; 如果发现异常活动,则限制访问:
定期检查你的日志,如果发现了一些自动访问(爬虫)的异常活动(例如来自同一个IP地址的许多类似的请求操作),那么你可以阻止或限制这些IP地址的访问。
具体来说,限制措施如下:
· 访问速率限制:
只允许用户(和爬虫)在一定时间内执行有限数量的操作 - 例如,只允许任何特定的IP地址或用户每秒进行几次搜索。这样就会减慢爬虫的使用,使爬取功能逐渐无效。如果操作的完成速度比实际用户要快得多或更快,你也可以显示一个验证码来阻止爬虫。
· 检测异常活动:
如果你发现了异常活动,例如来自某个特定的IP地址的许多类似的请求,或者是某个用户浏览了过多的页面或执行的搜索次数不同寻常,那么也可以阻止这类IP或用户的访问,或者是在后续的请求中显示验证码。
· 不要只是通过IP地址监控和限制访问速率 —— 也可以使用其他指标:
如果你阻止或限制访问速率,请不要仅在每个IP地址的基础上进行; 你可以使用其他指标和方法来识别特定的用户或爬虫。下面包括了一些可以帮助你识别特定用户/爬虫的指标:
o 用户填写表单的速度以及他们点击的按钮的位置;
o 你可以使用JavaScript收集客户端的大量信息,例如屏幕尺寸/分辨率,时区,已安装的字体等; 你可以使用这些信息来识别用户。
o Http协议头及其顺序,尤其是User-Agent。
例如,如果你发现从单个IP地址上发出了许多请求,则所有使用相同的User agent,屏幕尺寸(用JavaScript确定)的用户(此时应该是爬虫)始终以相同的方式和相同的时间间隔定期点击按钮,那么它可能是一个屏幕爬虫; 你可以暂时阻止类似的请求(例如,阻止来自特定的IP地址中相同的user agent和屏幕大小的所有请求),这样你就不会对该IP地址上的真实用户造成影响,例如:在共享互联网连接的情况下。
你还可以进一步的阻止爬虫,因为你可以识别类似的请求,如果这些请求来自不同的IP地址,那么意味着这可能是一个分布式Web 爬虫(使用僵尸网络或代理网络的爬虫)。如果你发现了还有很多相同的其他请求,但是它们来自不同的IP地址,那么你也可以阻止IP地址的访问。再次提醒一下,不要在无意中阻止了真实的用户。
这可以对运行JavaScript的屏幕截图类的爬虫很有效,因为你可以从中获取大量的信息。
Security Stack Exchange上面与此有关的相关问题:
· 如何识别出口IP地址相同的用户?
· 为什么人们在IP地址经常变化时使用IP地址黑名单?
· 请使用验证码替代临时阻止访问的方案:
实现访问速率限制的简单方法是在一段时间内临时阻止访问,但是使用验证码可能会更好一些,详细内容请参阅“验证码”部分。
要求注册和登录
如果你的网站可以做到需要创建帐户才能查看你的网站的内容的话,那么这对爬虫来说可能是一个很好的威慑,但对真实用户来说也可能是一个很好的威慑。
· 如果你要求客户端创建帐户和登录,那么你可以准确的跟踪用户和爬虫的操作。这样的话,你就可以轻松的检测某些帐户是何时被用于爬虫的,然后禁止掉这些用户。访问速率限制或检测滥用(例如在短时间内的大量搜索请求)也会变得更加容易,因为你可以识别特定的爬虫而不仅仅是识别出IP地址。
为了避免自动化创建许多帐户的脚本,你应该做以下这些事情:
· 注册时需要一个电子邮件地址,并且用户必须打开通过你所发送的链接来验证该电子邮件地址才能激活该帐户。每个电子邮件地址只允许一个帐户。
· 需要在注册/帐户创建期间显示验证码,以防止自动化脚本创建帐户。
要求创建帐户才能查看内容的做法会导致用户和搜索引擎不能正常访问; 如果你需要创建帐户才能查看文章,那么用户将会去其他网站,而不是去注册一个账户然后再查看文章。
阻止来自云托管主机和爬虫服务的IP地址的访问
有时,爬虫会从网络托管服务(如Amazon Web Services或Google App Engine)或VPSes运行。限制(或显示验证码)来源于此类云主机服务使用的IP地址请求访问你的网站。你还可以阻止从爬虫服务使用的IP地址的访问。
同样,你还可以限制代理或VPN提供商使用的IP地址的访问,因为爬虫可能会使用此类代理服务器来避免单个IP发出许多请求。
请注意,通过阻止代理服务器和VPN的访问,你将对真实用户产生负面的影响。
如果你要采取阻止访问的做法,请将你的错误消息进行调整
如果你采取了阻止/限制访问的手段,那么你应该确保不要告诉爬虫导致阻塞的实际原因,从而给爬虫制作者如何修复爬虫的线索。所以用文本显示错误页面可能是一个坏主意:
· 你的IP地址请求过于频繁,请稍后再试。
· 错误,User Agent不存在,非法访问!
相反,显示一个友好的错误消息,不要告诉爬虫是什么原因造成不能正常访问的。
· 抱歉,网站出了一些问题。如果问题仍然存在,你可以联系[email protected]。
这也是真正对用户友好的一种显示内容。你还应该考虑在后续的请求中不要直接显示验证码,以防真实用户看到这个错误消息,导致你阻止了合法用户的访问行为。
如果你的网站被爬虫访问,请使用Captchas。
Captchas(“完全自动化测试以分辨电脑和人类”)对于阻止爬虫非常有效。不幸的是,这种方式对正常用户的请求有干扰。
因此,当你怀疑你的网站可能被爬了,那么这种方式是非常有用的,因为这种方法只是阻止了Web 爬虫,而不会阻止真实的正常用户的访问。
使用Captchas时需要注意下面几个事情:
· 不要自己实现验证码,应该使用像Google的reCaptcha这样的东西:这比自己实现一个验证码要容易得多,它比一些模糊和扭曲的文本解决方案对用户来说更友好,而且比起自己实现验证码,它能更好的解决问题
· 不要在HTML标记中包含验证码的解决方案:实际上我已经看到一个网站在页面中嵌入了验证码的解决方案(虽然隐藏的很好)。但是不要这样做。还是推荐使用像reCaptcha这样的服务,如果你正确使用它,就不会出现问题。
· Captchas是可以批量验证的:在网上有一些低报酬的人工打码服务可以批量解决验证码的验证服务。所以,我在这里还是推荐使用reCaptcha,因为它具有很好的自我保护作用。这种服务不太可能被用于人工打码,除非你的数据真的很有价值。
将你的文本内容转成图片
你可以在服务器端将文本转换成图像然后在客户端显示,这种方法可以阻碍简单的爬虫提取文本。
然而,这对于屏幕阅读器,搜索引擎,性能以及其他的一些事情都是不利的。在某些方面(比如无障碍操作,例如美国残疾人法案)也可能是非法的,并且也很容易被一些OCR技术绕过,所以最好还是不要这样做。
你可以做类似于CSS精灵的东西,但是也同样会遇到上面的问题。
不要公开你的完整数据集:
如果可行的话,请不要为脚本或爬虫机器人提供所有数据集的方法。例如:你有一个新闻网站,有很多单独的文章。你可以通过现场搜索来搜索这些文章,并且如果你没有列出任何网站上的所有文章及其URL,那么这些文章将只能通过使用搜索来访问特征。这意味着一个想要从你的网站上获得所有文章的脚本将不得不搜索可能出现在你的文章中的所有可能的短语,才能找到文章的全部内容,这对于爬虫来说是很耗时的,而且效率低的可怕,所以爬虫一般都会放弃爬取数据。
如果是以下这些情况,那么这种方法将变得无效:
· 爬虫机器人或脚本并不想或需要完整的数据集。
· 你的文章的URL是一个看起来像 example.com/article.php?articleId=12345这种(和类似的东西)的格式,这将允许爬虫可以简单地迭代所有articleId的文章,并请求所有的文章内容。
· 还有其他方式可以最终找到所有的文章,比如通过编写一个脚本来跟踪其他文章的内容中的链接。
· 搜索“&”或“”的东西可以显示几乎所有的东西,这是一些需要注意的事情。(你只能返回前10或20个结果来避免这种情况)。
· 你需要搜索引擎来查找你的内容。