导语:确保你不会向外暴露任何API,甚至无意中的暴露。例如,如果你使用Adobe Flash或Java Applets(禁止执行)中的AJAX或网络请求来加载数据,那么查看网页上的网络请求并确定这些请求将在哪里进行,这都是一些微不足道的小事情,爬虫程序中会
不要对外暴露你的API,端点以及类似的东西:
确保你不会向外暴露任何API,甚至无意中的暴露。例如,如果你使用Adobe Flash或Java Applets(禁止执行)中的AJAX或网络请求来加载数据,那么查看网页上的网络请求并确定这些请求将在哪里进行,这都是一些微不足道的小事情,爬虫程序中会通过逆向工程使用这些端点。确保你模糊混淆了你的端点,使他们难以使别人使用,如上所述。
阻止HTML解析器和爬虫
由于HTML解析器可以通过从HTML中的可识别模式中提取内容,因此我们可以有意地改变这些模式来达到破坏这些爬虫的目的,甚至彻底让它们歇菜。大多数这些技巧也适用于其他爬虫,如网络蜘蛛和屏幕爬虫。
经常更改你的HTML内容
爬虫通过从HTML页面的特定的可识别部分提取内容,可以直接处理HTML。例如:如果你网站上的所有页面都有一个id 为article-content的div,其中包含了文章的文本,那么编写一个脚本访问你网站上的所有文章页面就很简单,并在每个文章页面提取id为article-content的div 的内容文本,爬虫就拥有了你的网站上的所有可以在其他地方重复使用的格式的文章。
如果你经常更改HTML和页面结构,则这种爬虫将无法工作。
· 你可以经常更改HTML中的id和class元素,甚至可以自动更改。所以,如果你div.article-content变成了这样的事情div.a4c36dda13eaf0,并且每周都会有变化,那么爬虫最初可以正常工作,但是一周之后就会歇菜。确保更改id / classe的长度,否则爬虫会通过div.[any-14-characters]来找到所需的div。小心别留下其他类似的“bug”。
· 如果没有办法从标记中找到所需的内容,则爬虫将按照HTML的结构方式执行此操作。所以,如果你所有的文章页面的相似之处是每个div内的div后的h1是文章内容,爬虫将获得基于这样的文章内容。为了突破这一点,你可以定期和随机地添加/删除额外的标记,例如。添加额外的div或span。使用现代服务器端HTML处理,这应该不是很难。
需要注意的事项:
· 执行,维护和调试会比较乏味。
· 你会阻碍缓存。特别是如果你更改了HTML元素的id或类,这将需要你的CSS和JavaScript文件做出相应的更改,这意味着每次更改它们时,都必须通过浏览器重新下载。这将导致重复访问者的页面加载时间更长,并增加服务器负载。如果你每周只更改一次,这不是一个大问题。
· 聪明的爬虫仍然可以通过推断实际内容的位置来获取你的内容,例如。通过知道页面上的一大块文本可能是实际的文章。这使得可以从页面中找到并提取所需的数据。 Boilerpipe 正是这样做的。
另外请参阅如何阻止根据XPath的抓取工具获取页面内容,以获取有关如何在PHP中实现的详细信息。
根据用户的位置更改HTML
这与前一个提示比较类似。如果你根据用户的位置/国家/地区(由IP地址确定)提供不同的HTML,则可能会影响爬虫的效率。例如,如果有人正在撰写一个从你的网站上删除数据的移动应用程序,那么它最初可以正常工作,但是当实际分配给用户时就会中断,因为这些用户可能位于不同的国家,从而获得不同的HTML嵌入式爬虫不是设计消费的。
经常更改HTML,通过这样做主动干掉爬虫!
看一个例子:如果你的网站上有一个搜索功能,位于example.com/search?query=somesearchquery,它返回以下HTML:
<div class="search-result"> <h3 class="search-result-title">Stack Overflow has become the world's most popular programming Q & A website</h3> <p class="search-result-excerpt">The website Stack Overflow has now become the most popular programming Q & A website, with 10 million questions and many users, which...</p> <a class"search-result-link" href="/stories/stack-overflow-has-become-the-most-popular">Read more</a> </div>
(等等,更多相同结构的div与搜索结果)
你可能已经猜到这很容易被爬虫突破:所有的爬虫需要做的就是用查询点击搜索URL,并从返回的HTML中提取所需的数据。除了如上所述定期更改HTML之外,你还可以将旧标记与旧的id和类放在一起,用CSS隐藏,并填写假数据,从而使爬虫误以为爬到了数据。以下是更改搜索结果页面的方法:
<div class="the-real-search-result"> <h3 class="the-real-search-result-title">Stack Overflow has become the world's most popular programming Q & A website</h3> <p class="the-real-search-result-excerpt">The website Stack Overflow has now become the most popular programming Q & A website, with 10 million questions and many users, which...</p> <a class"the-real-search-result-link" href="/stories/stack-overflow-has-become-the-most-popular">Read more</a> </div> <div class="search-result" style="display:none"> <h3 class="search-result-title">Visit example.com now, for all the latest Stack Overflow related news !</h3> <p class="search-result-excerpt">EXAMPLE.COM IS SO AWESOME, VISIT NOW! (Real users of your site will never see this, only the scrapers will.)</p> <a class"search-result-link" href="http://example.com/">Visit Now !</a> </div>
(更多的真实搜索结果)
这将意味着根据类或ID从HTML中提取数据的爬虫将继续看起来很有效,但是由于隐藏了CSS,因此它们将获得假数据,甚至是真实用户永远不会看到的数据。
将假的,不可见的蜜罐数据插入到你的页面
在上一个示例中添加内容,你可以添加隐藏的蜜罐项目到你的HTML页面。可以添加到先前描述的搜索结果页面的示例:
<div class="search-result" style="display:none"> <h3 class="search-result-title">This search result is here to prevent scraping</h3> <p class="search-result-excerpt">If you're a human and see this, please ignore it. If you're a scraper, please click the link below 🙂 Note that clicking the link below will block access to this site for 24 hours.</p> <a class"search-result-link" href="/scrapertrap/scrapertrap.php">I'm a scraper !</a> </div>
获取所有搜索结果的爬虫会选择这种做法,就像页面上的其他真实搜索结果一样,然后访问链接,查找所需的内容。一个真实的用户永远不会在第一个地方看到(由于它被CSS隐藏)内容,所以不会访问链接。真实的网络蜘蛛(如Google)也不会访问该链接,因为你在robots.txt中(不要忘记这一点!)配置了不允许/scrapertrap/被爬取。
你可以在scrapertrap.php中为访问它的IP地址做一些阻止访问的操作,或强制对该IP所有后续请求进行验证。
· 不要忘记在你的robots.txt文件中禁止/scrapertrap/,这样搜索引擎的机器人就不会爬取它。
· 你可以将此建议与之前提到的经常更改HTML的建议相结合。
· 经常改变这种变换方法,因为爬虫最终会学会突破限制。更改蜜罐网址和文字。还要考虑更改用于隐藏的内联CSS,并使用ID属性和外部CSS替代,因为scraper将学习避免任何style具有CSS属性用于隐藏内容的内容。
· 请注意,恶意人员可以在论坛(或其他地方)上发布[img]http://yoursite.com/scrapertrap/scrapertrap.php[img]的内容,因此用户访问该论坛时会发生DOS攻击,浏览器会点击你的蜜罐网址。因此,更改URL的前一个提示是重要的,你还可以查看引用者。
如果你检测到爬虫,请提供假的和无用的数据
如果你发现有些请求显然是一个爬虫,你可以提供假的和无用的数据; 这将影响爬虫从你的网站获得的数据。你也应该注意不要将这些假数据与实际数据区分开来,这样爬虫就不知道他们被戏耍了。
举个例子:如果你有个新闻网站; 如果你检测到爬虫,而不是阻止访问,只需提供假的,随机生成的文章,这将使爬虫获得中毒的数据。如果你把你伪造的数据或文章与真实的东西区分开来,那么爬虫就很难得到他们想要的东西,即实际的真实文章。
如果User Agent为空,则不接受请求
通常,懒惰的爬虫制作者不会发送User Agent头部的请求,而所有的浏览器以及搜索引擎的蜘蛛都会发送。
如果你收到User Agent头不存在的请求,你可以显示验证码,或者只是阻止或限制访问。(或者如上所述提供虚假的数据,或其他内容)
欺骗也不是一定可以起作用,但作为一种措施来防止写得不好的爬虫,这是值得做的事情。
如果User Agent是普通的爬虫,不接受请求; 爬虫使用黑名单过滤
在某些情况下,爬虫将使用没有真正的浏览器或搜索引擎蜘蛛使用的User Agent,例如:
· “Mozilla”(就是这样,没有别的,我看到过几个关于这个的问题,真正的浏览器永远不会使用这种UA)
· “Java 1.7.43_u43”(默认情况下,Java的HttpUrlConnection使用的是像这样的东西。)
· “BIZCO EasyScraping Studio 2.0”
· “wget”,“curl”,“libcurl”,..(Wget和cURL有时用于基本的Web 爬虫)
如果你发现网站上的爬虫使用了特定的User Agent字符串,并且它不被真正的浏览器或合法的网络蜘蛛使用,你还可以将其添加到你的黑名单中。
检查Referer头
可以将此方法添加到上一个项目中,你还可以检查[Referer](https://en.wikipedia.org/wiki/HTTP_referer)(是的,它是Referer,而不是推荐来源),因为懒惰的爬虫制作者可能不会发送这个HTTP头 ,或者总是发送相同的东西(有时候是“google.com”)。例如,如果用户来自搜索结果页面的文章页面,请检查Referer头是否存在,并指向该搜索结果页面。
当心:
· 真正的浏览器并不总是发送它;
· 欺骗是微不足道的。
作为一个补充措施,防止写得不好的爬虫可能值得实施此方案。
如果不请求资产(CSS,图片),它不是一个真正的浏览器。
一个真正的浏览器将(几乎总是)请求和下载资源,如图像和CSS。HTML解析器和爬虫不会仅仅对实际页面及其内容感兴趣。
你可以将请求记录到资产中,如果你只看到HTML的许多请求,那么它可能是一个爬虫。
请注意,搜索引擎机器人,旧的移动设备,屏幕阅读器和配置错误的设备可能也不会请求资产文件。
使用和要求cookies; 使用它们来跟踪用户和爬虫操作。
你可以要求启用cookies以查看你的网站。这将阻止没有经验的和新手的爬虫制作者,但是爬虫可以很容易地发送cookie。如果你确实使用并要求使用它们,则可以跟踪用户和爬虫操作,从而在每个用户而不是每个IP的基础上实施限速,阻止或显示验证码。
例如:当用户执行搜索时,设置唯一的标识cookie。查看结果页时,请验证该Cookie。如果用户打开所有的搜索结果(你可以从cookie中得知),那么它可能是一个爬虫。
使用Cookie可能无效,因为爬虫也可以发送Cookie,并根据需要丢弃它们。如果你的网站仅适用于Cookie,你还将阻止访问cookies的用户。
请注意,如果你使用JavaScript设置和检索Cookie,则会阻止不运行JavaScript的爬虫,因为它们无法检索并发送Cookie。
使用JavaScript + Ajax加载你的内容
你可以在页面本身加载后使用JavaScript + AJAX加载你的内容。这将使内容在不能运行JavaScript的HTML解析器正常渲染最终无法访问。这对于新手和没有经验的程序员撰写的爬虫通常是一个有效的阻止方法。
有以下几点要注意:
· 使用JavaScript加载实际的内容将降低用户体验和性能
· 搜索引擎也可能不会运行JavaScript,从而阻止他们索引你的内容。这可能不是搜索结果页面的问题,但可能是其他的东西,如文章页面。
· 知道他们正在做什么样的爬虫的程序员可以编写一个能够发现内容加载的端点并使用它们。
模糊你的标记,来自脚本的网络请求以及其他所有内容。
如果你使用Ajax和JavaScript加载数据,则需要混淆传输的数据。例如,你可以在服务器上对数据进行编码(具有简单的base64或更复杂的多层混淆,位移或甚至加密),然后在获取后将其解码并在客户端上通过Ajax显示。这意味着有人检查网络流量将不会立即看到你的页面如何工作和加载数据,并且对于某人直接从你的端点请求数据时会更加困难,因为它们将不得不对你的干扰算法进行逆向工程。
· 如果你使用Ajax来加载数据,则应该很难使用端点,而不是首先加载页面,例如通过要求一些会话密钥作为参数,你可以将其嵌入到JavaScript或HTML中。
· 你还可以将混淆的数据直接嵌入到初始HTML页面中,并使用JavaScript对其进行混淆和显示,从而避免额外的网络请求。这样做会使得使用不运行JavaScript的仅HTML分析器来提取数据变得更加困难,因为编写爬虫的那些数据库必须对JavaScript进行逆向工程(你也应该混淆)。
· 你可能需要定期更改你的混淆方法,以打破已经弄清楚的爬虫。
尽管如此,做这样的事情有下面几个缺点:
· 执行,维护和调试将是乏味的。
· 对于实际运行JavaScript,然后提取数据的爬虫和屏幕截图将无效。(最简单的HTML解析器不会运行JavaScript)
· 如果禁用JavaScript,这将使你的站点对真实用户无效。
· 性能和页面加载时间将受到影响。
非技术:
你的主机提供商可能会提供机器人和爬虫保护:
例如,CloudFlare提供了一个防bot和防爬保护,你只需要启用它,AWS也是如此。还有一个mod_evasive,一个Apache模块,让你轻松实现速率限制。
告诉别人不要非法爬取数据,有些人会尊重它
你应该告诉别人不要爬你的网站,例如 在你的条件或服务条款。有些人实际上会尊重这一点,而且未经许可不得从你的网站上删除数据。
找律师
他们知道如何处理侵犯版权,并可以发出停止信件。数字千年版权法案DMCA,这种方法是Stack Overflow和Stack Exchange使用的方法。
使你的数据可用,提供API:
这可能看起来适得其反,但你可以使你的数据容易获得,并且需要归因和链接返回到你的网站。也许甚至收取$$$
其他说明:
· 找到真正用户的可用性和爬虫保护之间的平衡:你所做的一切都会以某种方式对用户体验产生负面影响,因此你需要找到妥协的办法。
· 不要忘了你的移动网站和应用程序:如果你有一个移动版本的网站,请注意爬虫也可以爬Web页面。如果你有移动应用程序,那么也可以通过屏幕截图爬取,并且可以检查网络流量以确定其使用的REST端点。
· 如果你为特定浏览器提供特殊版本的网站,例如 旧版Internet Explorer的缩减版本,不要忘记爬虫也可以爬取这种Web页面。
· 结合使用这些技巧,挑选最适合你的技巧。
· 爬虫可以爬取其他爬虫的结果:如果有一个网站显示从你的网站上爬取的内容,其他爬虫则可以从爬虫的网站上爬取下来。
最有效的方法是什么?
根据我在这里撰写爬虫和帮助人们写下反爬虫的经验,最有效的方法如下:
· 经常更改HTML标记
· 使用蜜罐和假数据
· 使用模糊的JavaScript,AJAX和Cookies
· 速率限制和爬虫检测和随后的阻塞。