Post

Scraping and Anti-scraping

[toc]


网络数据收集

pic

ref:

数据收集是直接从在线网站中提取公开可用数据的过程。数据收集不仅依赖于官方信息来源,

  • 如果网站没有专用的 API,则使用网络爬虫是唯一的选择。
  • 但是,带有 API 的网站——尤其是如果他们对数据访问收费的话——通常几乎不可能使用第三方工具进行抓取。

保持合法和合乎道德

合法性

  • 只要不使用黑帽技术来获取数据或违反网站的隐私政策,就一目了然。
  • 还应该避免使用收集的数据做任何非法的事情,例如毫无根据的营销活动和有害的应用程序。

道德数据收集

  • 应该尊重网站所有者对其数据的权利。如果他们网站的部分或所有部分有机器人排除标准,请避免使用。
  • 这意味着他们不希望任何人未经明确许可就抓取他们的数据,即使这些数据是公开可用的。
  • 此外应该避免一次下载太多数据,因为这可能会导致网站服务器崩溃,并可能让被标记为DDoS 攻击。

Data Scraping vs Data Crawling区别

  • Data Scraping
    • 是从任何资源处检索信息(并不一定是web)
    • 而data scraping中则不需要去重。
  • crawling中最难的一件事是如何做好连续性爬取的协调关系。我们的spider在爬取时要足够有礼貌,以避免目的服务器不堪其扰而踢出spider。
  • 最后不同的crawler之间可能有冲突,但这种情况不会出现在data scraping上。
  • 需要爬取和解析parser

  • Data Crawling
    • 是在处理大数据时利用crawler自动获取最深层的信息
    • Scraping数据不需要依靠网站,而是可以通过本机、数据库或网页上的“save as”链接获取信息。而网络爬虫中的crawling则代表只能通过在网页上爬取数据。
    • 有些时候相同的网页内容显示在不同的网址中,因此数据去重(data deduplication)是crawling中比较智能的一个功能。
    • 只需要爬取

API数据提取

  • API 代表应用程序编程接口。但它不是数据提取工具,而是网站和软件所有者可以选择实施的功能。 API 充当中介,允许网站和软件进行通信和交换数据和信息。
  • 虽然网络抓取工具是一种工具,可让浏览和抓取网站最偏远的角落以获取数据,但 API 是在数据提取过程中构建的。

  • API 不会要求数据收集者尊重他们的隐私。他们将其强制执行到他们的代码中。

  • API 由构建结构和限制用户体验的规则组成。
    • 它们控制可以提取的数据类型、哪些数据源可以打开以供收集,以及请求频率类型。
    • 由于它们是网站提供的官方工具,不必担心使用代理服务器或阻止 IP 地址。
    • API 只会让访问所有者想要提供的数据。

Tools

为了阻止抓取(也称为 WebscrapingScreenscrapingWeb 数据挖掘Web 收集Web 数据提取 ),了解这些抓取工具的工作_原理很有帮助_,_进而_了解是什么阻止了它们正常工作。

有多种类型的刮刀,每一种的工作方式都不同:

  • 蜘蛛程序
    • 例如Google 的机器人或网站复制程序,例如HTtrack
    • 它们递归地跟踪指向其他页面的链接以获取数据。
    • 这些有时用于有针对性的抓取以获取特定数据,通常与 HTML 解析器结合使用以从每个页面中提取所需的数据。
  • HTML 解析器
    • 例如基于 Jsoup、Scrapy等的解析器。
    • 与基于 shell 脚本正则表达式的类似,它们通过基于 HTML 中的模式从页面中提取数据来工作,通常会忽略其他所有内容。
    • 例如:如果你的网站有搜索功能,这样的scraper可能会提交一个搜索请求,然后从结果页HTML中获取所有的结果链接及其标题,以便专门只获取搜索结果链接及其标题. 这些是最常见的。
  • Shell 脚本
    • 有时,会使用常见的 Unix 工具进行抓取:
    • Wget 或 Curl 下载页面,
    • Grep (Regex) 提取数据。
  • Screenscrapers
    • 基于例如。Selenium或PhantomJS
    • 它们在真实浏览器中打开网站,运行 JavaScript、AJAX 等,然后从网页中获取所需的文本
    • 通常通过:
      • 在加载页面并运行 JavaScript 后从浏览器获取 HTML,然后使用 HTML 解析器提取所需的数据。这些是最常见的,许多用于破坏 HTML 解析器/抓取器的方法也可以在这里使用。
      • 对渲染的页面进行截图,然后使用 OCR 从截图中提取所需的文本。这些很少见,只有真正想要数据的专用刮刀才会设置它。
  • 网页抓取服务
    • 例如ScrapingHub或Kimono。事实上,有些人的工作是弄清楚如何抓取网站并提取内容供其他人使用。
    • 不出所料,专业的抓取服务是最难阻止的,但是如果很难且费时地弄清楚如何抓取网站,那么这些(以及为此付费的人)可能不会费心去抓取网站。

    • 使用框架将网站嵌入到其他网站的页面中,并将网站嵌入到移动应用程序中。
    • 虽然不是技术上的抓取,但移动应用程序(Android 和 iOS)可以嵌入网站,并注入自定义 CSS 和 JavaScript,从而完全改变页面的外观。
  • 人工复制 - 粘贴:人们会复制并粘贴内容,以便在其他地方使用。

这些不同种类的刮板之间有很多重叠,即使它们使用不同的技术和方法,许多刮板的行为也会相似。


网络爬虫

basic

  • 网络爬虫是一种程序,可以自动浏览网络,它们搜寻网页上的关键字、内容和链接。
  • 这些爬虫可以有不同的名字,如bot,automatic indexer,和robot。
  • 一旦你键入一个搜索请求,这些爬虫扫描所有的包含这些词的相关网页,并返回一个巨大的索引库。
  • 当爬虫访问一个网站时,它们会搜索其他值得访问的网站。它们可以链接到新的网站,标记出和现有网站的变化和标记不通的链接。

比如如果你正在用Google搜索引擎,爬虫将通过服务器中索引出的结果访问指定的页面,然后取出存到Google的服务器中。 网络爬虫也会顺着网站中的超链接去访问其他的网站。 所以当你向搜索引擎询问“软件开发课程”时,将返回所有符合条件的页面。 网络爬虫被配置成可以管理这些网页,以便生成的数据又快又新。

  • 网络爬虫通过代理工作,以避免被网站安全、反垃圾邮件和反机器人技术阻止。
    • 使用代理服务器来隐藏他们的身份并屏蔽他们的 IP 地址,使其看起来像普通的用户流量。
    • 将工具设置为以慢得多的速度提取数据 – 与人类用户的速度相匹配。
  • 大多数网络爬虫会自动将数据转换为用户友好的格式。他们还将其编译为随时可用的可下载数据包,以便于访问。

Google内部的搜索机制是什么?

  • Google显示全球有超过60万亿的网页。
  • 网站所有者可以决定他们的网页可以通过何种方式被索引,也可以拒绝被索引。
  • 索引的规则建立在网页内容的质量和其他因素的排序上。
  • Google的算法会将搜索结果更好的展现出来,并为更高效的搜索提供一些特性,比如:拼写修正、即时性搜索建议、自动补全、同义词等。
  • 这些爬虫为提供准确的结果起到了重要的作用。但也需要网站所有者提供更准确、高质量易于检索的内容。谷歌检索规则删除的200种信息。

数据挖掘

  • 从数据库中提取出预测性的信息,为公司寻找信息节省时间。

  • 数据挖掘提供了很多的工具,可以根据用户之前的行为来预测将来的趋势,帮助企业进行知识驱动、前瞻性的决策。
    • 数据挖掘工具帮助最大限度的缩短过去花费在分析大量数据上的时间,同时还会通过特定的方式搜索容易被遗漏的信息。
    • 不适合人类手工做的事,数据挖掘可以完成。
  • 网络爬虫从不同网站中爬取出大量的资料后,这些数据仍是非结构化的,如JSON、CSV或XML格式。
  • 数据挖掘即是从这些数据中得到有用的信息。所以你可以说网络爬取是数据挖掘处理的第一步。

  • 企业越来越重视管理数据挖掘并遵循分析实践。医药、保险、商业等领域都有很多这样的例子。

图像挖掘——一种数据挖掘的应用

  • 从图像中提取出数据,如比对相同颜色、尺寸或价格。Google Takeout可以帮助用户提取信息。
  • 这对于想要提取信息却又不想泄露自己隐私、数据的用户来说是最佳的选择。
  • 利用Google Takeout,数据挖掘工作不需要将所有的图片存储在另外的硬盘中。

  • 微博网站Tumblr是另一个图像挖掘的例子。这里有大量的多媒体文件可以随时被提取出。

  • 图像挖掘的出现证明了这样一个事实:社交过程发生了巨大的变化,内容已经缩小到单纯的字幕,“视觉语法”的出现已经风靡社交媒体。

数据提取

  • 网络爬取和数据挖掘之后就是数据提取了。
  • 数据提取对于在线购物非常有用。
    • 有一些带有数据源的网站有很好的结构,如Amazon,
    • 也有一些仍然是非结构化的并深藏在网站里。
    • 想要从这些网站中提取数据,在搜索盒和过滤器中的请求需要细化,这些结果被安置在HTML中。
    • 只有一种特殊的爬虫可以解析HTML并提取出数据,包括产品名称、定价、变化、评价、反馈、产品编码等。

用Apache Nutch进行网络爬取

  • Apache Nutch是一个开源网络爬虫。
  • 数据可以通过另一个Apache工具Hadoop连接在一起。
  • 可以通过这里下载。可以通过Apache Solr存储大量的数据。

看一下Nutch的主要构件,Elasticsearch提取信息是如何工作的。

pic

  • 指令给到Nutch。
  • 所有种子文件的URL被injector收集并存储给CrawlBase。
  • CrawBase记录完整的URL以及它们的结果状态
  • 接下来Generator保存URL信息在Segments字典里。
  • Fetcher收集Crawlist上URL的内容,存储在Segments字典中
  • Parser分割各个网站的内容到设计好的处理器中
  • 最后Elasticsearch接管并为内容索引。

一些不错的爬虫

  • Scrapy。
    • Python的爬虫包。
    • 如果执行一些中等规模的爬虫工作,Scrapy是个不错的选择。有个特点是你可以插入一个新的函数却不影响它的核心。
  • Storm-crawler。
    • 对于低延迟可扩展网络爬虫来说是最佳选择。这也是一个开源程序,可扩展性强,在Apache Storm上运行。
    • 比Nutch好的优点是它为每一个用户的配置单独提取URL,而Nutch是分批处理。
    • 反过来Nutch的优点是前者有现成的包而后者不是。
  • Elasticsearch River Web。
    • 这个插件是Elasticsearch的一个爬虫应用。
    • 它可以用CSS请求来爬取并提取内容。

Attack

可能对初学者刮刀起作用的事情:

  • IP封锁
  • 使用大量的ajax
  • 检查引用请求标头
  • 需要登录

一般会有帮助的事情:

  • 每周改变你的布局
  • 机器人.txt

有助于但会让你的用户讨厌你的事情:

  • 验证码

防止网站抓取

我有一个相当大的音乐网站,里面有一个很大的艺术家数据库。我一直注意到其他音乐网站正在抓取我们网站的数据 (我在这里和那里输入虚拟艺术家姓名,然后在谷歌上搜索它们)。 如何防止屏幕刮擦?甚至有可能吗?

你不能完全阻止它,因为无论你做什么,坚定的刮板仍然可以弄清楚如何刮。但是,可以通过执行以下操作来停止大量抓取:

监控日志和流量模式 限制访问

具体来说,一些想法:

  • 定期检查日志 检测异常活动:
    • 如果看到异常活动,表明自动访问(抓取工具)的异常活动,
    • 例如来自特定 IP 地址的许多类似请求、有人查看过多页面或执行异常数量的搜索,可以阻止访问,或显示后续请求的验证码。
  • 使用其他指标:
    • 不要只通过 IP 地址进行监控和速率限制
    • 如果要进行阻止或速率限制,可以使用其他指标和方法来识别特定用户或刮刀。
    • 可以帮助识别特定用户/抓取工具的一些指标包括:
      • 用户填写表单的速度,以及他们点击按钮的位置;
      • 用 JavaScript 收集信息,比如屏幕大小/分辨率、时区、安装的字体等;可以使用它来识别用户。
      • HTTP 标头及其顺序,尤其是 User-Agent。
      • 例如
        • 从一个 IP 地址收到许多请求,所有请求都使用相同的用户代理、屏幕大小(由 JavaScript 确定),
        • 并且用户(在本例中为抓取工具)总是以相同的方式点击按钮,并且在每隔一段时间,它可能是一个屏幕刮刀;
        • 可以暂时阻止类似的请求(例如,阻止来自该特定 IP 地址的具有该用户代理和屏幕大小的所有请求),这样就不会对该 IP 地址上的真实用户造成不便,
        • 在共享互联网连接的情况下。
          • 还可以更进一步,因为可以识别类似的请求,即使它们来自不同的 IP 地址,表明分布式抓取(使用僵尸网络或代理网络的抓取)。如果收到许多其他相同的请求,但它们来自不同的 IP 地址,可以阻止。同样,请注意不要无意中阻止了真实用户。
        • 这对于运行 JavaScript 的屏幕抓取工具非常有效,因为可以从中获取大量信息。
  • 速率限制:
    • 仅允许用户(和抓取工具)在特定时间内执行有限数量的操作
    • 例如,仅允许每秒从任何特定 IP 地址或用户进行几次搜索。
    • 这将减慢刮刀的速度,并使它们无效。
    • 如果操作完成得比真实用户过快或快,还可以显示验证码。
  • 而不是暂时阻止访问,使用验证码:
    • 实现速率限制的简单方法是在一定时间内暂时阻止访问,但是使用验证码可能会更好

Security Stack Exchange 的相关问题:

  • 如何唯一标识具有相同外部IP地址的用户?了解更多详情,以及
  • 当IP地址经常变化时,为什么人们使用IP地址禁令?有关这些方法限制的信息。

基于 IP 的限制根本无效 - 这里有太多的公共代理服务器,还有 TOR… 它不会减慢抓取速度(对于那些_真正_想要你的数据的人)。


确保所有用户标头都是有效的

  • 我有时会提供尽可能多的标头以使我的刮板看起来像一个真实的用户,其中一些甚至不像 en-FU 那样真实或有效:)。 这是我通常提供的一些标题的列表。 ``` headers = { “Requested-URI”: “/example”, “Request-Method”: “GET”, “Remote-IP-Address”: “656.787.909.121”, “Remote-IP-Port”: “69696”, “Protocol-version”: “HTTP/1.1”, “Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8”, “Accept-Encoding”: “gzip,deflate”, “Accept-Language”: “en-FU,en;q=0.8”, “Cache-Control”: “max-age=0”, “Connection”: “keep-alive”, “Dnt”: “1”, “Host”: “https://example.com”, “Referer”: “https://example.com”, “Upgrade-Insecure-Requests”: “1”, “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36” }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
---


#### 如果用户代理为空/丢失,则不接受请求

- 通常爬虫不会随其请求发送用户代理标头,而所有浏览器和搜索引擎蜘蛛都会
- 如果收到不存在用户代理标头的请求,可以显示验证码,或者简单地阻止或限制访问。


> 基于**用户代理**的过滤根本没有帮助。任何认真的数据挖掘者都会在他的抓取工具中将其设置为正确的数据。

---

#### 如果用户代理是常见的抓取工具 则不要接受请求 黑名单

- 可以在发现已知屏幕抓取器用户代理字符串时设置黑名单。

- 在某些情况下,scraper 会使用一个没有真正的浏览器或搜索引擎蜘蛛使用的用户代理,例如:

- “Mozilla”(仅此而已,仅此而已。我在这里看到了一些关于抓取的问题,使用它。真正的浏览器永远不会只使用它)
- “Java 1.7.43\_u43”(默认情况下,Java 的 HttpUrlConnection 使用类似的东西。)
- “BIZCO EasyScraping Studio 2.0”
- "wget", "curl", "libcurl",..(Wget 和 cURL 有时用于基本抓取)

- 屏蔽常见的抓取用户代理,你会在主要/大型网站中看到这个,因为你不可能用“python3.4”作为你的用户代理来抓取它们。

- 如果发现网站上的爬虫使用了特定的用户代理字符串,而真实浏览器或合法蜘蛛并未使用该字符串,也可以将其添加到黑名单中。

> 知道自己在做什么的程序员可以设置用户代理字符串来模拟 Web 浏览器。


---


#### 需要注册和登录

- 如果网站可行,则需要创建帐户才能查看内容。这对爬虫来说是一个很好的威慑
- 创建和登录帐户,可以准确地跟踪用户和爬虫操作。
- 可以轻松检测特定帐户何时被用于抓取并禁止它。
- 诸如速率限制或检测滥用(例如短时间内大量搜索)之类的事情变得更容易,因为可以识别特定的抓取工具而不仅仅是 IP 地址。

为了避免脚本创建多个帐户"
- 需要一个用于注册的电子邮件地址,并通过发送必须打开才能激活帐户的链接来验证该电子邮件地址。每个电子邮件地址只允许一个帐户。
- 需要在注册/帐户创建期间解决验证码。

> 需要创建帐户才能查看内容将把用户和搜索引擎赶走;
> 需要创建帐户才能查看文章,用户将前往别处。

> 打败它的最简单方法(无需任何分析和/或编写登录协议脚本)就是以普通用户身份登录站点,使用 Mozilla,然后运行基于 Mozrepl 的抓取工具...

> _要求登录_对匿名机器人有帮助,但对想要抓取数据的人没有帮助。他只是将自己注册到网站作为普通用户。

> 屏幕抓取工具可能会设置一个帐户并可能巧妙地编写脚本来为他们​​登录。

---


#### 阻止来自云托管和抓取服务 IP 地址的访问

- 有时,抓取工具会通过 Web 托管服务运行,例如 Amazon Web Services 或 GAE,或 VPS。限制来自此类云托管服务使用的 IP 地址的请求访问网站(或显示验证码)。

- 可以限制来自代理或 VPN 提供商使用的 IP 地址的访问,因为抓取工具可能会使用此类代理服务器来避免检测到许多请求。
  - 通过阻止来自代理服务器和 VPN 的访问,将对真实用户产生负面影响。


---


#### 使错误消息变得难以描述

如果阻止/限制访问,应该确保没有告诉刮板是什么导致了堵塞,从而为他们提供了如何修复刮板的线索。

不好的错误页面:
- 来自 IP 地址的请求过多,请稍后重试。
- 错误,用户代理标头不存在!


友好的错误消息
- 不会告诉刮板是什么原因造成的
- 抱歉,出了一些问题。如果`helpdesk@example.com`问题仍然存在,可以通过 联系支持。
- 应该考虑为后续请求显示验证码而不是硬块,以防真实用户看到错误消息,这样就不会阻止,从而导致合法用户与联系。


---


#### 使用验证码

- 验证码(“完全自动化的测试以区分计算机和人类”)对于阻止抓取工具非常有效。

- 使用验证码并要求在返回页面之前完成验证。

- 当怀疑可能存在抓取工具并希望停止抓取时,它们非常有用,而且不会阻止访问,以防它不是抓取工具而是真实用户。如果怀疑是抓取工具,可能需要考虑在允许访问内容之前显示验证码。

使用验证码时需要注意的事项:

- 不要自己动手
  - 使用类似 Google 的reCaptcha 之类的东西:
  - 它比自己实现验证码要容易得多,
  - 它比自己可能想出的一些模糊和扭曲的文本解决方案更用户友好(用户通常只需要勾选一个框),
  - 而且对于脚本编写者来说,解决它比从站点提供的简单图像要困难得多

- 不要在 HTML 标记中包含验证码的解决方案
  - 网站,它_在页面本身中_提供了验证码的解决方案, 使它变得毫无用处。

- 验证码可以批量解决:
  - 除非的数据非常有价值,否则不太可能使用这种服务。
  - 有验证码解决服务,实际的、低薪的人工批量解决验证码。
  - 使用 reCaptcha 是一个好主意,因为它们有保护措施(例如用户有相对较短的时间来解决验证码)。


> **Captcha**(好的 - 像 reCaptcha)有很大帮助


---


#### 将文本内容作为图像提供

- 可以将文本渲染到图像服务器端,然后将其显示出来,这将阻碍简单的抓取工具提取文本。
- 这是非常可靠的,并且比 CAPTCHA 对用户的痛苦要小,这意味着他们将无法剪切和粘贴,并且无法很好地缩放或访问。

- 然而
  - 这对屏幕阅读器、搜索引擎、性能以及几乎所有其他方面都是不利的。
  - 在某些地方它也是非法的(由于可访问性,例如美国残疾人法案),并且使用某些 OCR 也很容易规避,所以不要这样做。
  - 可以用 CSS 精灵做类似的事情,但会遇到同样的问题。


> 很难抓取隐藏在图像中的数据。(例如,简单地将数据转换为服务器端的图像)。
> 使用“tesseract”(OCR)多次有帮助 - 但老实说 - 数据必须值得刮板的麻烦。(很多时候不值得)。

---


#### 不要公开完整数据集

- 如果可行,不要为脚本/机器人提供获取所有数据集的方法。
- 例子:
  - 新闻网站,有很多单独的文章。
  - 可以使这些文章只能通过站点搜索来访问它们,
  - 如果没有站点上 _所有_ 文章及其 URL的列表,则只能通过使用搜索来访问这些文章特征。
  - 这意味着想要从网站上删除所有文章的脚本必须搜索可能出现在文章中的所有可能的短语才能找到它们,
    - 这将非常耗时,效率极低,并且有望使刮板放弃。

如果出现以下情况,这将无效:

- 机器人/脚本 无论如何都不需要/需要完整的数据集。
- 文章是从类似于`example.com/article.php?articleId=12345`. 这(以及类似的东西)将允许抓取器简单地遍历所有`articleId`s 并以这种方式请求所有文章。
- 还有其他方法可以最终找到所有文章,例如通过编写脚本来跟踪文章中指向其他文章的链接。
- 搜索诸如“and”或“the”之类的内容几乎可以揭示所有内容,因此需要注意这一点。(可以通过仅返回前 10 或 20 个结果来避免这种情况)。
- 需要搜索引擎来查找内容。


---


#### 使用网站的Java小程序或Flash


- 最难的是其使用网站的**Java小程序或Flash**,和小程序使用**安全的HTTPS**内部请求本身
- 目前很少有网站使用它们。



---

#### 加密/编码数

- 仅限小型站点
- 许多提供加密/编码数据的网站,这些数据在任何编程语言中都无法解密,因为加密方法不存在。

- 通过加密和最小化输出(警告:这对大型网站来说这不是一个好主意)在 PHP 网站中实现了这一点,响应总是混乱的内容。

在 PHP 中最小化输出的示例(如何最小化 php 页面 html 输出?):

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
  function sanitize_output($buffer) {
    $search = array(
      '/\>[^\S ]+/s', // strip whitespaces after tags, except space
      '/[^\S ]+\</s', // strip whitespaces before tags, except space
      '/(\s)+/s'      // shorten multiple whitespace sequences
    );
    $replace = array('>', '<', '\\1');
    $buffer = preg_replace($search, $replace, $buffer);
    return $buffer;
  }
  ob_start("sanitize_output");
?> ```

不要暴露你的 API、端点和类似的东西:

  • 不公开任何 API,即使是无意的。
  • 例如,如果使用 AJAX 或来自 Adob​​e Flash 或 Java Applets(上帝保佑!)的网络请求来加载数据,那么查看来自页面的网络请求并找出这些请求的去向是微不足道的,并且然后逆向工程并在刮刀程序中使用这些端点。
  • 确保混淆了端点,并使其他人难以使用它们

经常更改 URL 路径

  • 当更改它时,请确保旧的继续工作,但仅限于一个用户可能打开浏览器的时间。
  • 很难预测新的 URL 路径是什么。
  • 如果它们的 URL 是硬编码的,这将使脚本难以获取它。最好用某种脚本来做到这一点。

阻止 HTML 解析器和抓取工具

  • 由于 HTML 解析器的工作原理是根据 HTML 中可识别的模式从页面中提取内容
  • 因此我们可以有意地更改这些模式以破坏这些爬虫,甚至搞砸它们。
  • 大多数这些技巧也适用于其他抓取工具,如蜘蛛和屏幕抓取工具。

根据用户的位置更改 HTML

  • 根据用户的位置/国家/地区(由 IP 地址确定)提供不同的 HTML,这可能会破坏提供给用户的抓取工具。
    • 例如
    • 一个移动应用程序,它会从网站上抓取数据,它最初可以正常工作,
    • 但在实际分发给用户时会中断,因为这些用户可能位于不同的国家/地区,因此会获得不同的 HTML,
    • 嵌入式刮刀不是为消耗而设计的。

经常更改 HTML

  • 直接处理 HTML 的抓取工具通过从 HTML 页面的特定、可识别部分提取内容来实现。
  • 例如
    • 网站上的所有页面都有一个divid 为 的article-content, 其中包含文章的文本
    • 那么编写一个脚本来访问网站上的所有文章页面,并提取article-contentdiv的内容文本是微不足道的
    • scraper 以可以在其他地方重复使用的格式保存网站上的所有文章。

频繁更改 HTML 和页面结构

  • 可以经常更改 HTML 中元素的 id 和类,甚至可以自动更改。
    • 因此,如果div.article-content变成类似div.a4c36dda13eaf0, 并且每周都在更改,则刮板最初可以正常工作,但一周后就会损坏。
    • 确保也更改 ids/classes 的长度,否则抓取工具将用于div.[any-14-characters]查找所需的 div。
    • 也要注意其他类似的洞..
  • 如果无法从标记中找到所需的内容,则抓取工具将根据 HTML 的结构方式进行查找。
    • 如果所有的文章页面都相似,divadiv之后的每个ah1都是文章内容,则抓取工具将根据该内容获取文章内容
    • 为了打破这种情况,可以定期和随机地向 HTML 添加/删除额外的标记
    • 例如。添加额外的divs 或spans。
    • 使用现代服务器端 HTML 处理,这应该不会太难。

需要注意的事项:

  • 实施、维护和调试将是乏味和困难的。

  • 阻碍缓存。
    • 特别是如果更改 HTML 元素的 id 或类,这将需要在 CSS 和 JavaScript 文件中进行相应的更改,这意味着每次更改它们时,浏览器都必须重新下载它们。
    • 这将导致重复访问者的页面加载时间更长,并增加服务器负载。
    • 如果一周只换一次,问题不大。
  • 聪明的抓取工具仍然可以通过推断实际内容的位置来获取内容
    • 例如。通过知道页面上的一大块文本很可能是实际的文章。
    • 这使得仍然可以从页面中查找和提取所需的数据。
    • Boilerpipe正是这样做的

从本质上讲,确保脚本不容易为每个类似页面找到实际所需的内容。

示例:网站上有一个搜索功能,位于example.com/search?query=somesearchquery,它返回以下 HTML:

1
2
3
4
5
6
    <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/story-link">Read more</a>
    </div>
    (And so on, lots more identically structured divs with search results)
  • 这很容易抓取:
    • 抓取工具所需要做的就是通过查询点击搜索 URL
    • 然后从返回的 HTML 中提取所需的数据。
    • 除了如上所述定期更改 HTML 之外,还可以保留带有旧 id 和类的旧标记,用 CSS 隐藏它,并用假数据填充它,从而毒害爬虫。
    • 以下是更改搜索结果页面的方式:
1
2
3
4
5
6
7
8
9
10
11
12
    <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/story-link">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 !</p>
      <a class"search-result-link" href="https://example.com/">Visit Now !</a>
    </div>
    (More real search results follow)

这意味着根据类或 ID 从 HTML 中提取数据的爬虫程序看起来将继续工作,但它们将获得虚假数据甚至广告,这些数据是真实用户永远不会看到的,因为它们被 CSS 隐藏了。


将虚假的、不可见的蜜罐数据插入页面

1
2
3
4
5
6
    <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 are a human and see this, please ignore it. If you are 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 am a scraper !</a>
    </div>
    (The actual, real, search results follow.)

将不可见的蜜罐项目添加到 HTML 中以捕获刮刀。

  • 为获取所有搜索结果而编写的爬虫程序会选择它,就像页面上的任何其他真实搜索结果一样,并访问链接,寻找所需的内容。
  • 一个真正的人根本不会看到它(因为它被 CSS 隐藏了),也不会访问链接。

可以scrapertrap.php执行一些操作

  • 例如阻止访问它的 IP 地址的访问,或强制对来自该 IP 的所有后续请求进行验证码。

  • 由于/scrapertrap/在 robots.txt 中不允许,因此 Google 等真正理想的蜘蛛也不会访问该链接。
  • 不要忘记/scrapertrap/在 robots.txt 文件中禁止蜜罐 ( ),以免搜索引擎机器人落入其中。

将此与之前频繁更改 HTML 的技巧结合起来。

  • 经常更改这一点,因为刮板最终会学会避免它。
  • 更改蜜罐 URL 和文本。还想考虑更改用于隐藏的内联 CSS,并改用 ID 属性和外部 CSS,因为刮板将学会避免任何具有style用于隐藏内容的 CSS 属性的内容。也尝试只启用它有时,所以刮板最初可以工作,但一段时间后会中断。这也适用于之前的提示。

  • 恶意人员可以通过共享指向蜜罐的链接,甚至将该链接作为图像嵌入某处(例如在论坛上)来阻止真实用户的访问。
  • 经常更改 URL,并使任何禁止时间相对较短。

如果检测到刮刀,则提供虚假和无用的数据

  • 如果检测到明显是刮刀的内容,则可以提供虚假和无用的数据;这将破坏刮板从网站获取的数据。
  • 使这些虚假数据与真实数据无法区分开来,以便抓取者不知道他们被搞砸了。

  • 例如:
  • 新闻网站如果检测到爬虫,不阻止访问,而是提供虚假的、随机生成的文章
  • 这将毒害爬虫获取的数据。
  • 如果你让你的虚假数据与真实数据无法区分,你将很难让抓取者获得他们想要的东西,即真实的、真实的数据。

如果它不请求资产(CSS、图像),它就不是真正的浏览器。

  • 真正的浏览器将(几乎总是)请求和下载诸如图像和 CSS 之类的资产。
  • HTML 解析器和抓取器不会,因为它们只对实际页面及其内容感兴趣。
  • 可以记录对资产的请求,如果看到大量仅针对 HTML 的请求,则它可能是一个抓取工具。
  • 请注意,搜索引擎机器人、古老的移动设备、屏幕阅读器和配置错误的设备也可能不会请求资产。

使用和需要cookies 跟踪用户和刮刀操作

  • 可以要求启用 cookie 以查看网站。这将阻止没有经验和新手的爬虫编写者,但是爬虫很容易发送 cookie。
  • 可以使用它们跟踪用户和抓取工具的操作,从而基于每个用户而不是每个 IP 实施速率限制、阻止或显示验证码。

  • 例如:
    • 当用户进行搜索时,设置一个唯一的识别cookie。
    • 查看结果页面时,请验证该 cookie。
    • 如果用户打开所有搜索结果(可以从 cookie 中看出),那么它可能是一个刮板。
  • 使用 cookie 可能无效,因为抓取工具也可以随请求发送 cookie,并根据需要丢弃它们。
  • 如果站点仅使用 cookie,还将阻止禁用 cookie 的真实用户访问。
  • 如果使用 JavaScript 来设置和检索 cookie,将阻止不运行 JavaScript 的抓取工具,因为它们无法检索和发送带有请求的 cookie。

使用 JavaScript + Ajax 加载内容

  • 可以在页面本身加载后使用 JavaScript + AJAX 加载内容。
  • 这将使不运行 JavaScript 的 HTML 解析器无法访问内容。
  • 这对于编写爬虫程序的新手和没有经验的程序员来说通常是一种有效的威慑。

意识到:

  • 使用 JavaScript 加载实际内容会降低用户体验和性能

  • 搜索引擎也可能不会运行 JavaScript,从而阻止它们将内容编入索引。这可能不是搜索结果页面的问题,但可能是其他内容的问题,例如文章页面。

  • 示例

    • https://www.bkstr.com/。
    • 他们使用 aj/s 算法来设置 cookie,然后重新加载页面,以便它可以使用 cookie 来验证请求是否正在浏览器中运行。
    • 专为抓取而构建的桌面应用程序肯定可以做到这一点,但它会阻止大多数 cURL 类型的抓取。

混淆标记、来自脚本的网络请求以及其他所有内容。

  • 如果使用 Ajax 和 JavaScript 加载数据,请混淆传输的数据。
    • 例如,
    • 可以在服务器上对数据进行编码(使用像 base64 这样简单或更复杂的东西)
    • 然后在通过 Ajax 获取后解码并在客户端上显示它。
    • 这将意味着检查网络流量的人不会立即看到页面如何工作和加载数据,并且有人直接从端点请求请求数据将更加困难,因为他们将不得不对解扰算法进行逆向工程。
  • 如果确实使用 Ajax 加载数据,应该在不首先加载页面的情况下使端点难以使用
  • 例如,需要一些会话密钥作为参数,可以将其嵌入到 JavaScript 或 HTML 中。

  • 还可以将混淆后的数据直接嵌入到初始 HTML 页面中,并使用 JavaScript 对其进行去混淆和显示,这样可以避免额外的网络请求。
  • 这样做会使使用不运行 JavaScript 的纯 HTML 解析器提取数据变得更加困难,因为编写刮板的人必须对 JavaScript 进行逆向工程(也应该对其进行混淆)。

但是,这样做有几个缺点:

  • 实施、维护和调试将是乏味和困难的。

  • 它对实际运行 JavaScript 然后提取数据的抓取工具和屏幕抓取工具无效。(尽管大多数简单的 HTML 解析器不运行 JavaScript)

  • 如果他们禁用了 JavaScript,它会使网站对真实用户不起作用。

  • 性能和页面加载时间将受到影响。


非技术

  • 告诉人们不要刮,有人会尊重它

  • 找律师


使数据可用,提供 API

  • 可以让数据轻松可用,并需要归属和返回网站的链接。

  • 提供 XML API 来访问数据;以一种易于使用的方式。如

  • 通过这种方式,可以以有效的方式提供功能的子集,至少确保爬虫不会消耗掉 HTTP 请求和大量带宽。
  • 然后你所要做的就是说服想要你的数据的人使用 API。;)

各种各样的

  • 还有一些商业爬虫保护服务,例如 Cloudflare 或Distill Networks的反爬虫

  • 在真实用户的可用性和防刮擦性之间找到平衡:你所做的一切都会以一种或另一种方式对用户体验产生负面影响,找到妥协。

  • 不要忘记移动网站和应用程序。如果有一个移动应用程序,也可以对其进行屏幕抓取,并且可以检查网络流量以确定它使用的 REST 端点。

  • 抓取工具可以抓取其他抓取工具:如果有一个网站的内容从网站抓取,则其他抓取工具可以从该抓取工具的网站抓取。


robots.txt

假设已经设置了robots.txt.

正如其他人所提到的,抓取工具几乎可以伪造其活动的每个方面,并且可能很难识别来自坏人的请求。

考虑:

  1. 设置一个页面,/jail.html
  2. 禁止访问页面robots.txt(因此尊敬的蜘蛛将永远不会访问)。
  3. 在其中一个页面上放置一个链接,用 CSS ( display: none)隐藏它。
  4. 记录访问者的 IP 地址到/jail.html.
  • 这可能会帮助快速识别来自公然无视robots.txt.
  • 你可能也想使你的/jail.html整个整个网站具有相同的,准确的标记为正常的网页,而是用假数据(/jail/album/63ajdka/jail/track/3aads8等)。这样,在有机会完全阻止它们之前,不会向不良抓取工具发出“异常输入”警报。

如果某个特定 IP 地址的访问速度非常快,那么在几次访问后 (5-10) 将其 IP 地址 + 浏览器信息放入文件或数据库中。(这将是一个后台进程并一直运行或在几分钟后安排。)制作另一个脚本来继续检查那些可疑的 IP 地址。

  1. 如果用户代理是已知的搜索引擎,如谷歌、必应、雅虎(可以通过谷歌搜索找到有关用户代理的更多信息)。
    1. 然后你必须看到https://www.iplists.com/。此列表并尝试匹配模式。
    2. 如果它看起来像一个伪造的用户代理,则要求在下次访问时填写验证码。(需要对机器人 IP 地址进行更多研究。我知道这是可以实现的,还可以尝试使用 IP 地址的 whois。这可能会有所帮助。)
  2. 没有搜索机器人的用户代理:
    1. 只需在下次访问时要求填写 CAPTCHA。

第一的:

  • 如果有人真的想要你的数据
  • 不能有效地(技术上)隐藏你的数据
  • 如果“普通用户”_应该可以_公开访问数据

尝试使用一些技术障碍是不值得的,导致:

  • 通过恶化他们的用户体验来给你的普通用户
  • 到常规和受欢迎的机器人(搜索引擎)
  • 等等…

HMTL

  • 最简单的方法是解析纯 HTML 页面,具有明确定义的结构和 css 类。
  • 例如,使用 Firebug 检查元素并在我的刮板中使用正确的 Xpath 和/或 CSS 路径就足够了。

可以动态生成 HTML 结构,也可以动态生成 CSS 类名(以及 CSS 本身)(例如,通过使用一些随机类名)

  • 但是
  • 希望以一致的方式将信息呈现给普通用户
  • 例如再次 - 再次分析页面结构以设置刮板就足够了。
  • 并且可以通过分析一些“已知内容”来自动完成
    • 一旦有人已经知道(通过较早的刮擦),例如:
    • 什么包含有关“菲尔柯林斯”的信息
    • 足够显示“phil collins”页面并(自动)分析“今天”页面的结构:)
  • 无法更改每个响应的结构,因为普通用户会讨厌。此外,这会给(维护)带来更多麻烦,而不是刮板。
  • XPath 或 CSS 路径可由抓取脚本根据已知内容自动确定。

Ajax - 一开始有点难,但很多时候会加快抓取过程:) - 为什么?

  • 在分析请求和响应时,我只是设置了自己的代理服务器(用 perl 编写)并且我的 Firefox 正在使用它。当然,因为它是我自己的代理 - 它是完全隐藏的 - 目标服务器将其视为常规浏览器。(因此,没有 X-Forwarded-for 和此类标题)。基于代理日志,大多数情况下可以确定 ajax 请求的“逻辑”,例如我可以跳过大部分 html 抓取,而只使用结构良好的 ajax 响应(主要是 JSON 格式)。

所以,_ajax_没有多大帮助……

使用大量 javascript 函数的页面。

这里可以使用两种基本方法:

  • 解压并理解 JS 并创建一个遵循 Javascript 逻辑的刮刀
  • 或仅使用 Mozilla 和Mozrepl进行抓取。
  • 例如
    • 真正的抓取是在全功能的启用 javascript 的浏览器中完成的,
    • 该浏览器被编程为单击正确的元素并直接从浏览器窗口获取“解码”响应。

这种抓取很慢(抓取是在常规浏览器中完成的),但它是

  • 非常容易设置和使用
  • 几乎不可能反击它:)
  • 无论如何都需要“缓慢”来应对“阻止基于相同 IP 的快速请求”

请记住:如果想将数据(以友好的方式)发布给普通用户,那么隐藏数据几乎是不可能的。

所以,

  • 使数据易于访问 - 通过某些 API
    • 这允许轻松访问数据
    • 例如从抓取中卸载服务器 - 对有好处
  • 设置正确的使用权限(例如,必须引用来源)
  • 许多数据不受版权保护 - 并且很难保护它们
  • 添加一些虚假数据(正如已经完成的那样)并使用合法工具
    • 正如其他人已经说过的,发送“停止和终止信”
    • 其他法律诉讼(起诉等)可能成本太高且难以胜诉(尤其是针对非美国网站)

对此的快速方法是设置一个诱杀/机器人陷阱。

  1. 制作一个页面,如果它打开了一定次数甚至根本没有打开,则会收集某些信息,例如 IP 等(也可以考虑违规或模式,但该页面根本不必打开)。

  2. 在使用 CSS display:none; 隐藏的页面中创建指向此内容的链接。或左:-9999px;位置:绝对;尝试将其放置在不太可能被忽略的地方,例如内容所在的位置而不是页脚,因为有时机器人可以选择忘记页面的某些部分。

  3. 在 robots.txt 文件中,为不希望友好机器人(大声笑,就像他们有快乐的脸!)收集信息并将此页面设置为其中一个页面的页面设置一大堆禁止规则。

  4. 现在,如果一个友好的机器人通过它应该忽略该页面。是的,但这还不够好。制作更多这些页面或以某种方式重新路由页面以接受不同的名称。然后在 robots.txt 文件中的这些陷阱页面旁边放置更多禁止规则,并与要忽略的页面一起放置。

  5. 收集这些机器人或进入这些页面的任何人的 IP,不要禁止它们,但可以在内容中显示杂乱的文本,例如随机数、版权声明、特定文本字符串、显示可怕的图片,基本上任何阻碍好的内容。还可以设置指向一个页面的链接,该页面将永远加载即。在 php 中你可以使用 sleep() 函数。如果它有某种检测来绕过加载时间过长的页面,这将反击爬虫,因为一些编写良好的机器人设置为一次处理 X 数量的链接。

  6. 制作了特定的文本字符串/句子,去最喜欢的搜索引擎搜索它们,它可能会显示内容在哪里结束。

无论如何,如果从战术上和创造性地思考,这可能是一个很好的起点。最好的办法是了解机器人的工作原理。

我还会考虑欺骗一些 ID 或页面元素上的属性显示方式:

1
<a class="someclass" href="../xyz/abc" rel="nofollow" title="sometitle">

每次都会改变其形式,因为某些机器人可能会被设置为在页面或目标元素中寻找特定模式。

1
2
3
<a title="sometitle" href="../xyz/abc" rel="nofollow" class="someclass">

id="p-12802" > id="p-00392"

预格式化文本

  • 将内容作为 XML 属性、URL 编码字符串、带有 HTML 编码 JSON 的预格式化文本或数据 URI 提供
  • 然后在客户端将其转换为 HTML。
  • 以下是一些执行此操作的网站:

  • 斯凯奇:XML

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
      <document
       filename=""
       height=""
       width=""
       title="SKECHERS"
       linkType=""
       linkUrl=""
       imageMap=""
       href=&quot;https://www.bobsfromskechers.com&quot;
       alt=&quot;BOBS from Skechers&quot;
       title=&quot;BOBS from Skechers&quot;
      />
    
  • Chrome 网上应用店:JSON

    1
    
      <script type="text/javascript" src="https://apis.google.com/js/plusone.js">{"lang": "en", "parsetags": "explicit"}</script>
    
  • 必应新闻:数据 URL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      <script type="text/javascript">
        //<![CDATA[
        (function()
          {
          var x;x=_ge('emb7');
          if(x)
            {
            x.src='data:image/jpeg;base64,/*...*/';
            }
          }() )
    
  • Protopage : URL 编码字符串

    1
    
      unescape('Rolling%20Stone%20%3a%20Rock%20and%20Roll%20Daily')
    
  • TiddlyWiki:HTML 实体 + 预先格式化的 JSON

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
         <pre>
         {&quot;tiddlers&quot;:
          {
          &quot;GettingStarted&quot;:
            {
            &quot;title&quot;: &quot;GettingStarted&quot;,
            &quot;text&quot;: &quot;Welcome to TiddlyWiki,
            }
          }
         }
         </pre>
    
  • 亚马逊:延迟加载

    1
    2
    
      amzn.copilot.jQuery=i;amzn.copilot.jQuery(document).ready(function(){d(b);f(c,function() {amzn.copilot.setup({serviceEndPoint:h.vipUrl,isContinuedSession:true})})})},f=function(i,h){var j=document.createElement("script");j.type="text/javascript";j.src=i;j.async=true;j.onload=h;a.appendChild(j)},d=function(h){var i=document.createElement("link");i.type="text/css";i.rel="stylesheet";i.href=h;a.appendChild(i)}})();
      amzn.copilot.checkCoPilotSession({jsUrl : 'https://z-ecx.images-amazon.com/images/G/01/browser-scripts/cs-copilot-customer-js/cs-copilot-customer-js-min-1875890922._V1_.js', cssUrl : 'https://z-ecx.images-amazon.com/images/G/01/browser-scripts/cs-copilot-customer-css/cs-copilot-customer-css-min-2367001420._V1_.css', vipUrl : 'https://copilot.amazon.com'
    
  • XMLCalabash:命名空间 XML + 自定义 MIME 类型 + 自定义文件扩展名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
         <p:declare-step type="pxp:zip">
              <p:input port="source" sequence="true" primary="true"/>
              <p:input port="manifest"/>
              <p:output port="result"/>
              <p:option name="href" required="true" cx:type="xsd:anyURI"/>
              <p:option name="compression-method" cx:type="stored|deflated"/>
              <p:option name="compression-level" cx:type="smallest|fastest|default|huffman|none"/>
              <p:option name="command" select="'update'" cx:type="update|freshen|create|delete"/>
         </p:declare-step>
    

.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.