编程技术类爬虫我爱编程

<HTTP权威指南>读书笔记 ---- 网络爬虫

2017-06-27  本文已影响1544人  Samuel_帽衫

网络爬虫

<p>网络爬虫(web crawler)能够在无需人类干预的情况下自动进行一系列Web事务处理的软件程序。很多爬虫会从一个Web站点逛到另一个Web站点,获取内容,跟踪超链,并对它们找到的数据进行处理。根据这些爬虫自动探查Web站点的方式,网络爬虫也可称作网络蜘蛛、蚂蚁、机器人等。</p>

爬虫及爬行方式

<p>Web爬虫会递归地对各种信息性Web站点进行遍历,获取第一个Web页面,然后获取那个页面指向的所有Web页面,然后是那些页面指向的所有Web页面,依此类推。递归地追踪这些Web链接的爬虫会沿着HTML超链创建的网络"爬行",所以将其称为爬虫(crawler)或蜘蛛(spider)。因特网搜索引擎使用爬虫在Web上游荡,并把它们碰到的文档全部拉回来。然后对这些文档进行处理,形成一个可搜索的数据库,以便用户查找包含了特定单词的文档。网上有数万亿的Web页面需要查找和取回,这些搜索引擎必然是些最复杂的爬虫。</p>

从根集开始

<p>在把饥饿的爬虫放出去之前,需要给它一个起始点。爬虫开始访问的URL初始集合被称作根集(root set)。挑选根集时,应该从足够多不同的站点中选择URL,这样,爬遍所有的链接才能最终到达大部分你感兴趣的Web页面。根集中并不需要有很多页面,就可以涵盖一大片Web结构,通常,一个好的根集会包括一些大的流行Web站点,比如,一个新创建页面的列表和一个不经常被链接的无名页面列表。很多大规模的爬虫产品,比如因特网搜索引擎使用的那些爬虫,都为用户提供了向根集中提交新页面或无名页面的方式。这个根集会随时间推移而增长,是所有新爬虫的种子列表。</p>

链接的提取以及相对链接的标准化

<p>爬虫在Web上移动时,会不停地对HTML页面进行解析。它要对所解析的每个页面上的URL链接进行分析,并将这些链接添加到需要爬行的页面列表中去。随着爬虫的前进,当其发现需要探查的新链接时,这个列表常常会迅速地扩张。爬虫要通过简单的HTML解析,将这些链接提取出来,并将相对URL转换为绝对形式。</p>

避免环路的出现

<p>爬虫在Web上爬行时,要特别小心不要陷入循环,或环路(cycle)之中。爬虫必须知道它们到过何处,以避免环路的出现。环路会造成爬虫陷阱,这些陷阱会暂停或减缓爬虫的爬行进程。</p>

循环与复制

<p>至少出于下列三个原因,环路对爬虫来说是有害的:</p>

记录曾经到过哪些地方

<p>记录曾经到过哪些地方并不总是一件容易的事。因特网上有数十亿个不同的Web页面,其中还不包括那些由动态网关产生的内容。如果要爬行世界范围内的一大块Web内容,就要做好访问数十亿URL的准备。记录下哪些URL已经访问过了是件很具挑战的事情。由于URL的数量巨大,所以,要使用复杂的数据结构以便快速判定哪些URL是曾经访问过的。数据结构在访问速度和内存使用方面都应该是非常高效的。数亿URL需要具备快速搜索结构,所以速度是很重要的。穷举搜索URL列表是根本不可能的。爬虫至少要用到搜索树或散列表,以快速判定某个URL是否被访问过。数亿URL还会占用大量的空间。</p>
<p>大规模Web爬虫对其访问过的地址进行管理时使用的一些有用的技术:</p>

别名与爬虫环路

<p>由于URL"别名"的存在,即使使用了正确的数据结构,有时也很难分辨出以前是否访问过某个页面。如果两个URL看起来不一样,但实际指向的是同一资源,就称这两个URL互为"别名"。</p>

规范化URL

<p>大多数Web爬虫都试图通过将URL"规范化"为标准格式来消除上面那些显而易见的别名。爬虫首先可先将每个URL都转化为规范化的格式,就可以消除大部分别名问题了。但如果不知道特定Web服务器的相关信息,爬虫就没什么好办法来避免别名问题了。URL规范化可以消除一些基本的语法别名,但爬虫还会遇到其他的、将URL转换为标准形式也无法消除的URL别名。</p>
<p>通过下列步骤将每个URL都转化为规范化的格式:</p>

<p>特定Web服务器的相关信息:</p>

文件系统连接环路

<p>文件系统中的符号连接会造成特定的潜在环路,因为它们会在目录层次深度有限的情况下,造成深度无限的假象。符号连接环路通常是由无心错误造成的,但也可能会恶意地为爬虫制造这样的陷阱。</p>

动态虚拟Web空间

<p>可能会有意创建一些复杂的循环来陷害那些无辜的、毫无戒备的爬虫。尤其是,发布一个看起来像普通文件,实际上却是网关应用程序的URL是很容易的。这个应用程序可以在传输中构造出包含了到同一服务器上虚构URL链接的HTML。请求这些虚构的URL时,服务器就会捏造出一个带有新的虚构URL的新HTML页面来。即使这个Web服务器实际上并不包含任何文件,它也可以通过无限虚拟的Web空间将爬虫带入"梦境"。更糟的是,每次的URL和HTML看起来都有很大的不同,爬虫很难检测到环路。更常见的情况是,可能会在无意中通过符号连接或动态内容构造出爬虫陷阱。比如,一个基于CGI的日历程序,它会生成一个月历和一个指向下个月的链接。真正的用户是不会不停地请求下个月的链接的,但不了解其内容的动态特性的爬虫可能会不断向这些资源发出无穷的请求。</p>

避免循环和重复

<p>没有什么简单明了的方式可以避免所有的环路。实际上,经过良好设计的爬虫中要包含一组试探方式,以避免环路的出现。总的说来,爬虫的自动化程度越高(人为的监管越少),越可能陷入麻烦之中。爬虫的实现者需要做一些取舍——这些试探方式有助于避免问题的出现,但你可能会终止扫描那些看起来可疑的有效内容,因此这种方式也是"有损失"的。爬行Web这样规模庞大的数据集时,好的爬虫探测法总是会不断改进其工作的。随着新的资源类型不断加入Web,它会随着时间的推移构建出一些新的规则,并采纳这些规则。好的规则总是在不断发展之中的。当受到错误爬虫影响的资源(服务器、网络带宽等)处于可管理状态,或者处于执行爬行工作的人的控制之下(比如在内部站点上)时,很多较小的、更具个性的爬虫就会绕开这些问题。这些爬虫更多的是依赖人类的监视来防止这些问题的 发生。</p>
<p>爬虫会遇到的各种危险的Web中,有些技术的使用可以使爬虫有更好的表现:</p>

爬虫的HTTP

<p>爬虫和所有其他HTTP客户端程序并没有什么区别。它们也要遵守HTTP规范中的规则。发出HTTP请求并将自己广播成"HTTP/1.1"客户端的爬虫也要使用正确的HTTP请求首部。很多爬虫都试图只实现请求它们所查找内容所需的最小HTTP集。这会引发一些问题;但短期内这种行为不会发生什么改变。结果就是,很多爬虫发出的都是"HTTP/1.0"请求,因为这个协议的要求很少。</p>

识别请求首部

<p>尽管爬虫倾向于只支持最小的HTTP集,但大部分爬虫确实实现并发送了一些识别首部——最值得一提的就是User-Agent首部。建议爬虫实现者们发送一些基本的首部信息,以通知各站点爬虫的能力、爬虫的标识符,以及它是从何处起源的。</p>
<p>在追踪错误爬虫的所有者,以及向服务器提供爬虫所能处理的内容类型时,这些信息都是很有用的。鼓励爬虫实现者们使用的基本识别首部包括如下内容:</p>

虚拟主机

<p>爬虫实现者要支持Host首部。随着虚拟主机的流行,请求中不包含Host首部的话,可能会使爬虫将错误的内容与一个特定的URL关联起来。因此,"HTTP/1.1"要求使用Host首部。在默认情况下,大多数服务器都被配置为提供一个特定的站点。因此,不包含Host首部的爬虫向提供两个站点的服务器发起请求时。</p>

条件请求

<p>尽量减少爬虫所要获取内容的数量通常是很有意义的。对因特网搜索引擎爬虫来说,需要下载的潜在页面有数十亿,所以,只在内容发生变化时才重新获取内容是很有意义的。有些爬虫实现了条件HTTP请求,它们会对时间戳或实体标签进行比较,看看它们最近获取的版本是否已经升级了。这与HTTP缓存查看已获取资源的本地副本是否有效的方法非常相似。</p>

对响应的处理

<p>很多爬虫的兴趣主要在于用简单的GET方法来获取所请求的内容,所以,一般不会在处理响应的方式上花费太多时间。但是,使用了某些HTTP特性(比如条件请求)的爬虫,以及那些想要更好地探索服务器,并与服务器进行交互的爬虫则要能够对各种不同类型的HTTP响应进行处理。</p>

User-Agent导向

<p>Web管理员应该记住,会有很多的爬虫来访问它们的站点,因此要做好接收爬虫请求的准备。很多站点会为不同的用户代理进行内容优化,并尝试着对浏览器类型进行检测,以确保能够支持各种站点特性。这样的话,当实际的HTTP客户端根本不是浏览器,而是爬虫的时候,站点为爬虫提供的就会是出错页面而不是页面内容了。在某些搜索引擎上执行文本搜索,搜索短语"your browser does not support frames"(你的浏览器不支持框架),会生成一个包含那条短语的出错页面列表。站点管理员应该设计一个处理爬虫请求的策略。比如,它们可以为所有其他特性不太丰富的浏览器和爬虫开发一些页面,而不是将其内容限定在特定浏览器所支持的范围。至少,管理员应该知道爬虫是会访问其站点的,不应该在爬虫访问时感到猝不及防。</p>

行为不当的爬虫

<p>不守规矩的爬虫会造成很多严重问题:</p>

拒绝爬虫访问

<p>爬虫社团能够理解爬虫访问Web站点时可能引发的问题。1994 年,人们提出了一项简单的自愿约束技术,可以将爬虫阻挡在不适合它的地方之外,并为网站管理员提供了一种能够更好地控制爬虫行为的机制。这个标准被称为"拒绝爬虫访问标准",但通常只是根据存储访问控制信息的文件而将其称为"robots.txt"。"robots.txt"的思想很简单。所有Web服务器都可以在服务器的文档根目录中提供一个可选的、名为"robots.txt"的文件。这个文件包含的信息说明了爬虫可以访问服务器的哪些部分。如果爬虫遵循这个自愿约束标准,它会在访问那个站点的所有其他资源之前,从Web站点请求"robots.txt"文件。</p>

拒绝爬虫访问标准

<p>拒绝爬虫访问标准是一个临时标准。不同的厂商实现了这个标准的不同子集。但是,具备一些对爬虫访问Web站点的管理能力,即使并不完美,也总比一点儿都没有要好,而且大部分主要的生产厂商和搜索引擎爬虫都支持这个拒绝访问标准。现在大多数爬虫采用的都是标准v0.0或v1.0。版本v2.0要复杂得多,没有得到广泛的应用。</p>

Web站点和robots.txt文件

<p>如果一个Web站点有"robots.txt"文件,那么在访问这个Web站点上的任意URL之前,爬虫都必须获取它并对其进行处理。由主机名和端口号定义的整个Web站点上仅有一个"robots.txt"资源。如果这个站点是虚拟主机,每个虚拟的docroot都可以有一个不同的robots.txt文件,像所有其他文件一样。通常不能在Web站点上单独的子目录中安装"本地robots.txt文件"。管理员要负责创建一个聚合型"robots.txt"文件,用以描述Web站点上所有内容的拒绝访问规则。</p>

robots.txt文件的格式

<p>"robots.txt"文件采用了非常简单的,面向行的语法。"robots.txt"文件中有三种类型的行:空行、注释行和规则行。规则行看起来就像HTTP首部一样,用于模式匹配。"robots.txt"文件中的行可以从逻辑上划分成"记录"。每条记录都为一组特定的爬虫描述了一组排斥规则。通过这种方式,可以为不同的爬虫使用不同的排斥规则。每条记录中都包含了一组规则行,由一个空行或文件结束符终止。记录以一个或多个User-Agent行开始,说明哪些爬虫会受此记录的影响,后面跟着一些Disallow和Allow行,用来说明这些爬虫可以访问哪些URL。</p>
<p>此例显示了一个"robots.txt"文件,这个文件允许爬虫Slurp和Webcrawler访问除了private子目录下那些文件之外所有的文件。这个文件还会阻止所有其他爬虫访问那个站点上的任何内容。</p>

# this robots.txt file allows Slurp & Webcrawler to crawl
# the public parts of our site, but no other robots...

User-Agent: slurp
User-Agent: webcrawler
Disallow: /private

User-Agent: *
Disallow:

其他有关robots.txt的知识

<p>解析 robots.txt 文件时还需遵循其他一些规则。</p>

缓存和robots.txt的过期

<p>如果一个爬虫在每次访问文件之前都要重新获取"robots.txt"文件,Web服务器上的负载就会加倍,爬虫的效率也会降低。爬虫使用的替代方法是,它会周期性地获取"robots.txt"文件,并将得到的文件缓存起来。爬虫会使用这个robots.txt文件的缓存副本,直到其过期为止。原始服务器和爬虫都会使用标准的HTTP存控制机制来控制"robots.txt"文件的缓存。爬虫应该留意HTTP响应中的Cache-Control和Expires首部。现在很多产品级爬虫都不是"HTTP/1.1"的客户端;管理员应该意识到这些爬虫不一定能够理解那些为"robots.txt"资源提供的缓存指令。如果没有提供Cache-Control指令,规范草案允许将其缓存7天。但实际上,这个时间通常太长了。不了解"robots.txt"文件的Web服务器管理员通常会在响应爬虫的访问时创建一个新的文件,但如果将缺乏信息的"robots.txt"文件缓存一周,新创建的"robots.txt"文件就没什么效果了,站点管理员会责怪爬虫管理员没有遵守拒绝爬虫访问标准。</p>

搜索引擎

<p>得到最广泛使用的Web爬虫都是因特网搜索引擎。因特网搜索引擎可以帮助用户找到世界范围内涉及任意主题的文档。现在Web上很多最流行的站点都是搜索引擎。很多Web用户将其作为起始点,它们会为用户提供宝贵的服务,帮助用户找到他们感兴趣的信息。Web爬虫为因特网搜索引擎提供信息,它们获取Web上的文档,并允许搜索引擎创建索引,用以说明哪些文档中有哪些词存在。搜索引擎是Web爬虫的主要来源。</p>

大格局

<p>Web发展的初期,搜索引擎就是一些相当简单的数据库,可以帮助用户在Web上定位文档。现在,Web上有数十亿可供访问的页面,搜索引擎已经成为因特网用户查找信息不可缺少的工具。它们在不断地发展,以应对Web庞大的规模,因此,现在已经变得相当复杂了。</p>
<p>面对数十亿的Web页面,和数百万要查找信息的用户,搜索引擎要用复杂的爬虫来获取这数十亿Web页面,还要使用复杂的查询引擎来处理数百万用户产生的查询负荷。产品级Web爬虫的任务,要获取搜索索引所需的页面,它要发出数十亿条HTTP请求。如果每条请求都要花半秒钟的时间(对有些服务器来说可能慢了,对另一些服务器来说可能快了)。如果请求是连续发出的,结果差不多是5700天!很显然,大型爬虫得更聪明一些,要对请求进行并行处理,并使用大量服务器来完成这项任务。但由于其规模庞大,爬行整个Web仍然是件十分艰巨的任务。</p>

现代搜索引擎结构

<p>现在的搜索引擎都构建了一些名为"全文索引"的复杂本地数据库,装载了全世界的Web页面,以及这些页面所包含的内容。这些索引就像Web上所有文档的卡片目录一样。搜索引擎爬虫会搜集Web页面,把它们带回家,并将其添加到全文索引中去。同时,搜索引擎用户会通过HotBot或Google这样的Web搜索网关对全文索引进行查询。Web页面总是在不断地发生变化,而且爬行一大块Web要花费很长的时间,所以全文索引充其量也就是Web的一个快照。</p>

全文索引

<p>全文索引就是一个数据库,给它一个单词,它可以立即提供包含那个单词的所有文档。创建了索引之后,就不需要对文档自身进行扫描了。</p>

发布查询请求

<p>用户向Web搜索引擎网关发布一条请求时,会填写一个HTML表单,他的浏览器会用一个HTTP GET或POST请求将这个表单发送给网关。网关程序对搜索请求进行解析,并将Web UI查询转换成搜索全文索引所需的表达式。</p>

对结果进行排序,并提供查询结果

<p>旦搜索引擎通过其索引得到了查询结果,网关应用程序会获取结果,并将其拼成结果页面提供给终端用户。很多Web页面都可能包含任意指定的单词,所以搜索引擎采用了一些很聪明的算法,尝试着对结果进行排名。为了将相关度最高的结果提供给用户,搜索引擎要知道应该按照什么顺序来提供结果列表中的文档。这被称为相关性排名(relevancy ranking)——这是对一系列搜索结果的评分和排序处理。为了更好地辅助这一进程,在爬行Web的过程中都会进行数据统计。比如,对指向指定页面的链接进行计数有助于判断其流行程度,还可以用此信息来衡量提供结果的顺序。算法、爬行中获取的辅助信息以及搜索引擎所使用的其他技巧都是保守最森严的秘密。</p>

欺诈

<p>在搜索请求得到的前几个结果中没有看到自己想要查找的内容时,用户通常会感到很沮丧,因此,查找站点时搜索结果的顺序是很重要的。在搜索管理员们认为能够最好地描述其站点功能的单词时,会有众多因素激励着这些管理员,努力使其站点排在靠近结果顶端的位置上,尤其是那些依赖于用户找到它们,并使用其服务的商业站点。这种对较好排列位置的期待引发了很多对搜索系统的博弈,也在搜索引擎的实现者和那些想方设法要将其站点列在突出位置的人之间引发了持久的拉锯战。很多管理员都列出了无数关键字(有些是毫不相关的),使用一些假冒页面,或者采用欺诈行为——甚至会用网关应用程序来生成一些在某些特定单词上可以更好地欺骗搜索引擎相关性算法的假冒页面。这么做的结果就是,搜索引擎和爬虫实现者们要不断地修改相关性算法,以便更有效地抓住这些欺诈者。</p>

上一篇 下一篇

猜你喜欢

热点阅读