注意:这是我在Stack Overflow上答案的扩展版本,我将其放在GitHub上,因为它太长了(最多30k个字符,超过40k个字符)。
从本质上讲,阻止抓取意味着您需要使脚本和计算机难以从网站上获取所需数据,而对实际用户和搜索引擎则不那么困难。
不幸的是,这很困难,您将需要在防止抓取和降低真实用户和搜索引擎的可访问性之间做出权衡。
为了阻止抓取(也称为Web抓取,屏幕抓取,Web数据挖掘,Web收集或Web数据提取),它有助于了解这些抓取工具的工作原理以及阻止它们正常工作的原因,这就是这个答案关于。
通常,编写这些刮板程序是为了从您的站点中提取特定信息,例如文章,搜索结果,产品详细信息,或者在您情况下是艺术家和专辑信息。通常,人们会刮擦网站以获取特定数据,以便在自己的网站上重复使用(并从您的内容中赚钱!),或者为您的网站构建替代前端(例如移动应用程序),甚至只是用于私人研究或分析目的。
诸如Google的漫游器之类的蜘蛛或诸如HTtrack之类的网站复制器会访问您的网站,并以递归方式跟踪指向其他页面的链接以获取数据。这些有时有时用于有针对性的抓取以获得特定的数据,通常与HTML解析器结合使用以从每个页面提取所需的数据。
Shell脚本:有时,常用的Unix工具用于抓取:Wget或Curl用于下载页面,而Grep(Regex)则通常使用Shell脚本来提取所需的数据。这些是最简单的抓取工具,也是最易碎的一种(永远不要尝试使用regex解析HTML!)。因此,这些是最容易折断和拧紧的刮刀。
HTML抓取器和解析器,例如基于Jsoup,Scrapy和其他许多工具。与基于shell脚本的正则表达式类似,它们的工作原理是基于HTML中的模式从页面中提取数据,而通常忽略其他所有内容。
因此,例如:如果您的网站具有搜索功能,则这样的抓取工具可能会提交HTTP请求进行搜索,然后从结果页HTML中获取所有结果链接及其标题,有时可能需要数百次才能进行数百次不同的搜索,以便仅获取搜索结果链接及其标题。这些是最常见的。
屏幕抓取工具,例如基于Selenium或PhantomJS,它们实际上是在真实的浏览器中打开您的网站,运行JavaScript,AJAX等,然后通常通过以下方式从网页中获取所需的文本:
加载页面并运行JavaScript之后,从浏览器获取HTML,然后使用HTML解析器提取所需的数据或文本。这些是最常见的,因此许多用于破坏HTML解析器/刮除器的方法在这里也适用。
截取渲染页面的屏幕截图,然后使用OCR从屏幕截图中提取所需的文本。这些很少见,只有真正想要您的数据的专用刮板才能进行设置。
基于浏览器的屏幕抓屏程序运行脚本,呈现HTML并表现得像人类在浏览您的网站时一样,因此处理起来更加困难。
Web爬网服务,例如ScrapingHub或和服。实际上,有些人的工作是弄清楚如何抓取您的网站并提取内容供他人使用。这些服务器有时使用大型的代理服务器网络和不断变化的IP地址来规避限制和限制,因此它们尤其成问题。
毫不奇怪,专业的抓取服务最难以阻止,但是如果您很难弄清楚如何抓取您的网站,那么这些人(以及为此付费的人)可能就不会打扰您。
将您的网站嵌入带有框架的其他网站页面中,并将您的网站嵌入移动应用程序中。
尽管从技术上讲并不是很容易,但这也是一个问题,因为移动应用程序(Android和iOS)可以嵌入您的网站,甚至注入自定义CSS和JavaScript,从而完全改变您网站的外观,并仅显示所需的信息,例如文章内容本身或搜索结果列表,并隐藏页眉,页脚或广告之类的内容。
人工复制和粘贴:人们将复制并粘贴您的内容,以便在其他地方使用。不幸的是,您对此无能为力。
这些不同种类的刮板之间有很多重叠之处,即使它们使用不同的技术和方法来获取内容,许多刮板的行为也相似。
这套技巧主要是我自己的想法,写刮板时遇到的各种困难,以及来自Internet网上的一些信息和想法。
定期检查您的日志,如果发现异常活动指示自动访问(爬网程序),例如来自同一IP地址的许多类似操作,则可以阻止或限制访问。
仅允许用户(和刮板)在特定时间内执行有限数量的操作-例如,仅允许每秒从任何特定IP地址或用户进行几次搜索。这将减慢刮板的速度,并使它们无效。如果动作完成得比真实用户快或快,您还可以显示验证码。
如果您看到异常活动,例如来自特定IP地址的许多类似请求,某人查看过多页面或执行异常数量的搜索,则可以阻止访问或为后续请求显示验证码。
如果您设置了限制或速率限制,则不要仅基于每个IP地址进行限制;您可以使用其他指标和方法来识别特定用户或抓取工具。可以帮助您识别特定用户/刮板的一些指标包括:
您可以使用JavaScript收集很多信息,例如屏幕大小/分辨率,时区,安装的字体等;您可以使用它来识别用户。
例如,如果您从一个IP地址收到许多请求,则所有请求都使用相同的用户代理,屏幕大小(由JavaScript确定)和用户(在这种情况下为抓取工具)总是以相同的方式并在定期间隔,可能是屏幕刮板;并且您可以暂时阻止类似的请求(例如,阻止来自该特定IP地址的具有该用户代理和屏幕尺寸的所有请求),这样您就不会在该IP地址上给实际用户带来不便。如果共享Internet连接。
您也可以更进一步,因为您可以识别相似的请求,即使它们来自不同的IP地址,也表示分布式抓取(使用僵尸网络或代理网络的抓取器)。如果收到许多其他相同的请求,但它们来自不同的IP地址,则可以阻止。同样,请注意不要无意间阻止了真实用户。
这对于运行JavaScript的屏幕抓取工具可能是有效的,因为您可以从中获取很多信息。
实施速率限制的简单方法是在一段时间内暂时阻止访问,但是使用验证码可能更好,请参阅下文中的验证码部分。
如果您的网站可行,则需要创建帐户才能查看您的内容。这对于刮板来说是很好的威慑力,但是对于实际用户也是很好的威慑力。
如果需要创建和登录帐户,则可以准确跟踪用户和刮板操作。这样,您可以轻松检测到何时将特定帐户用于抓取并禁止它。速率限制或检测滥用(例如在短时间内进行大量搜索)之类的事情变得更加容易,因为您可以识别特定的抓取工具,而不仅仅是IP地址。
要求提供电子邮件地址进行注册,并通过发送必须激活才能激活帐户的链接来验证该电子邮件地址。每个电子邮件地址仅允许一个帐户。
再次要求在注册/帐户创建期间解决验证码,以防止脚本创建帐户。
需要创建帐户来查看内容将驱使用户和搜索引擎离开;如果您需要创建帐户才能查看文章,则用户将转到其他地方。
有时,抓取工具将通过Web托管服务运行,例如Amazon Web Services或Google app Engine或VPSes。限制对源自此类云托管服务使用的IP地址的请求的访问(或显示验证码)。您也可以阻止来自抓取服务使用的IP地址的访问。
同样,您也可以限制来自代理或VPN提供商使用的IP地址的访问,因为爬虫可能会使用此类代理服务器来避免检测到许多请求。
请注意,通过阻止来自代理服务器和VPN的访问,将会对真实用户产生负面影响。
如果您确实要阻止/限制访问,则应确保不要告诉刮板是什么原因导致刮板,从而为他们提供有关如何修复刮板的线索。因此,一个糟糕的主意将是显示带有类似以下内容的错误页面:
而是显示一条友好的错误消息,该消息不会告诉刮板是什么原因造成的。像这样的东西要好得多:
如果实际用户看到这样的错误页面,这对用户也更加友好。您还应该考虑显示用于后续请求的验证码,而不是硬阻止,以防真实用户看到错误消息,从而您不会阻止并导致合法用户与您联系。
验证码(“完全自动化的测试可以区分计算机和人”)对于阻止刮板非常有效。不幸的是,它们在刺激用户方面也非常有效。
这样,当您怀疑可能的刮板并希望停止刮板时,如果它们不是刮板而是真正的用户,则它们也将在不阻止访问的情况下很有用。如果您怀疑刮板,则可能需要考虑在允许访问内容之前显示验证码。
不要自己动手,使用类似Google的reCaptcha之类的东西:它比自己实施验证码容易得多,比您可能会想出的一些模糊和扭曲的文本解决方案更加用户友好(用户通常只需要勾选一个方框即可) ),而且脚本编写者要解决的问题比从您的网站提供的简单图片还要难得多
不要在HTML标记中包含针对验证码的解决方案:我实际上已经看到一个网站在页面本身中提供了针对验证码的解决方案(尽管非常隐蔽),从而使其变得毫无用处。不要做这样的事情。同样,使用诸如reCaptcha之类的服务,也不会出现此类问题(如果使用正确)。
可以完全解决验证码:存在一些解决验证码的服务,在这些服务中,实际的低薪人员可以批量解决验证码。同样,在这里使用reCaptcha是一个好主意,因为它们具有保护功能(例如,用户为解决验证码所花费的时间相对较短)。除非您的数据确实有价值,否则不太可能使用这种服务。
您可以将文本渲染到图像服务器端,然后将其显示出来,这将妨碍简单的抓取工具提取文本。
但是,这对于屏幕阅读器,搜索引擎,性能以及几乎所有其他方面都是不利的。在某些地方,这也是非法的(由于无障碍环境,例如《美国残疾人法》),而且某些OCR也很容易绕开,所以不要这样做。
您可以对CSS Sprite进行类似的操作,但是会遇到相同的问题。
如果可行,请不要为脚本/机器人提供一种获取所有数据集的方法。例如:您有一个新闻站点,其中包含很多单独的文章。您可以通过在站点搜索中搜索来使这些文章只能被访问,并且,如果您没有站点上所有文章及其URL的列表,则只能通过搜索来访问这些文章。特征。这意味着想要将所有文章从您的网站上删除的脚本将不得不搜索所有可能出现在文章中的短语,以便找到所有短语,这将很费时,效率极低并且有望使刮板放弃。
您的文章是通过类似于example.com/article.php?articleId=12345的URL提供的。这个(和类似的东西)将允许抓取器简单地遍历所有articleIds并以这种方式请求所有文章。
还有其他方法可以最终找到所有文章,例如通过编写脚本来跟随文章中指向其他文章的链接。
搜索“ and”或“ the”之类的内容几乎可以揭示所有内容,因此需要注意。 (您可以通过仅返回前10或20个结果来避免这种情况)。
确保您不公开任何API,即使是无意间也是如此。例如,如果您正在Adobe Flash或Java Applets(禁止使用!)中使用AJAX或网络请求来加载数据,那么查看页面中的网络请求并弄清楚这些请求的去向是很简单的,并且然后进行反向工程,并在刮板程序中使用这些端点。确保对端点进行混淆处理,使端点难以使用,如所述。
由于HTML解析器的工作原理是基于HTML中可识别的模式从页面中提取内容,因此我们可以有意地更改这些模式,以破坏这些抓取工具,甚至将它们拼凑在一起。这些技巧大多数也适用于其他刮板,例如蜘蛛和筛板刮板。
直接处理HTML的抓取工具通过从HTML页面的特定的,可识别的部分中提取内容来进行处理。例如:如果您网站上的所有页面都具有一个ID为article-content的div,其中包含文章的文本,那么编写脚本来访问您网站上所有文章页面并提取内容是很简单的每个文章页面上文章内容div的文本,以及voilà,该抓取工具都以可在其他地方重复使用的格式来存储您网站中的所有文章。
如果您经常更改HTML和页面结构,则此类抓取工具将不再起作用。
您可以频繁更改HTML中元素的id和元素类,甚至可以自动更改。因此,如果您的div.article-content变成类似于div.a4c36dda13eaf0之类的东西,并且每周更改一次,则刮板最初会正常工作,但一周后会损坏。请确保也更改ID /类的长度,否则抓取工具将使用div。[any-14-characters]来查找所需的div。还要提防其他类似的孔。
如果没有办法从标记中找到所需的内容,则抓取工具将通过HTML的结构方式进行查找。因此,如果所有文章页面都是相似的,并且h1之后的div内的每个div都是文章内容,那么抓取工具将根据该内容获得文章内容。同样,要打破这一点,您可以定期或随机地向HTML添加/删除额外的标记,例如。添加额外的div或span。使用现代服务器端HTML处理,这应该不太困难。
您将阻止缓存。特别是如果您更改HTML元素的ID或类,这将需要在CSS和JavaScript文件中进行相应的更改,这意味着每次更改它们时,浏览器都必须重新下载它们。对于重复访问者,这将导致更长的页面加载时间,并增加服务器负载。如果您仅每周更改一次,则不会有太大问题。
聪明的抓取工具仍然可以通过推断实际内容的位置来获取您的内容,例如知道页面上的一大段文字很可能是实际的文章。这使得仍然可以从页面中查找和提取所需的数据。锅炉管正是这样做的。
本质上,请确保脚本很难为每个相似的页面找到实际的所需内容。
另请参阅如何防止依赖XPath的爬网程序获取页面内容,以获取有关如何在PHP中实现的详细信息。
这有点类似于上一个技巧。如果您根据用户的位置/国家/地区(由IP地址确定)提供不同的HTML,则可能会破坏提供给用户的抓取工具。例如,如果某人正在编写一个移动应用程序,该应用程序会从您的网站上抓取数据,则该应用程序最初可以正常运行,但在实际分发给用户时会中断,因为这些用户可能在不同的国家,因此获得了不同的HTML,嵌入式刮板并非旨在消耗。
示例:您的网站上有一个搜索功能,位于example.com/search?query=somesearchquery,该功能返回以下HTML:
堆栈溢出已成为世界上最受欢迎的编程问答网站 该网站Stack Overflow现在已成为最受欢迎的编程问答网站,拥有1000万个问题并有许多用户,这... 阅读更多 (依此类推,具有搜索结果的结构更相同的div)
正如您可能已经猜到的那样,这很容易抓取:抓取器所需要做的就是用查询命中搜索URL,然后从返回的HTML中提取所需的数据。除了如上所述定期更改HTML之外,您还可以在旧标记中保留旧的ID和类,用CSS隐藏它,并用假数据填充它,从而使刮板中毒。更改搜索结果页面的方法如下:
堆栈溢出已成为世界上最受欢迎的编程问答网站 了解更多 立即访问example.com,以获取所有与Stack Overflow相关的最新新闻! EXAMPLE.COM非常棒,请立即访问! (您网站的实际用户将永远不会看到此信息,只有刮板会看到。) 立即访问! (更多实际搜索结果如下)
这意味着为基于类或ID从HTML提取数据而编写的抓取工具似乎将继续起作用,但是它们将获得伪造的数据甚至是广告,这些数据是真实用户无法看到的,因为它们被CSS隐藏了。
加上前面的示例,您可以将不可见的蜜罐项目添加到HTML中以捕获抓取工具。可以将一个示例添加到先前描述的搜索结果页面中:
此搜索结果是为了防止抓取 如果您是人类并且看到此内容,请忽略它。如果您是刮板手,请单击下面的链接:-)请注意,单击下面的链接将在24小时内阻止对该网站的访问。 <一个类“搜索结果链接” href =“ / scrapert