网络爬虫
网络爬虫(web crawler)能够在无需人类干预的情况下自动进行一系列Web事务处理的软件程序。很多爬虫会从一个Web站点逛到另一个Web站点,获取内容,跟踪超链,并对它们找到的数据进行处理。根据这些爬虫自动探查Web站点的方式,网络爬虫也可称作网络蜘蛛、蚂蚁、机器人等。
爬虫及爬行方式
Web爬虫会递归地对各种信息性Web站点进行遍历,获取第一个Web页面,然后获取那个页面指向的所有Web页面,然后是那些页面指向的所有Web页面,依此类推。递归地追踪这些Web链接的爬虫会沿着HTML超链创建的网络”爬行”,所以将其称为爬虫(crawler)或蜘蛛(spider)。因特网搜索引擎使用爬虫在Web上游荡,并把它们碰到的文档全部拉回来。然后对这些文档进行处理,形成一个可搜索的数据库,以便用户查找包含了特定单词的文档。网上有数万亿的Web页面需要查找和取回,这些搜索引擎必然是些最复杂的爬虫。
从根集开始
在把饥饿的爬虫放出去之前,需要给它一个起始点。爬虫开始访问的URL初始集合被称作根集(root set)。挑选根集时,应该从足够多不同的站点中选择URL,这样,爬遍所有的链接才能最终到达大部分你感兴趣的Web页面。根集中并不需要有很多页面,就可以涵盖一大片Web结构,通常,一个好的根集会包括一些大的流行Web站点,比如,一个新创建页面的列表和一个不经常被链接的无名页面列表。很多大规模的爬虫产品,比如因特网搜索引擎使用的那些爬虫,都为用户提供了向根集中提交新页面或无名页面的方式。这个根集会随时间推移而增长,是所有新爬虫的种子列表。
链接的提取以及相对链接的标准化
爬虫在Web上移动时,会不停地对HTML页面进行解析。它要对所解析的每个页面上的URL链接进行分析,并将这些链接添加到需要爬行的页面列表中去。随着爬虫的前进,当其发现需要探查的新链接时,这个列表常常会迅速地扩张。爬虫要通过简单的HTML解析,将这些链接提取出来,并将相对URL转换为绝对形式。
避免环路的出现
爬虫在Web上爬行时,要特别小心不要陷入循环,或环路(cycle)之中。爬虫必须知道它们到过何处,以避免环路的出现。环路会造成爬虫陷阱,这些陷阱会暂停或减缓爬虫的爬行进程。
循环与复制
至少出于下列三个原因,环路对爬虫来说是有害的:
- 它们会使爬虫陷入可能会将其困住的循环之中。循环会使未经良好设计的爬虫不停地兜圈子,把所有时间都耗费在不停地获取相同的页面上。爬虫会消耗掉很多网络带宽,可能完全无法获取任何其他页面了。
- 爬虫不断地获取相同的页面时,另一端的Web服务器也在遭受着打击。如果爬虫与服务器连接良好,它就会击垮Web站点,阻止所有真实用户访问这个站点。这种拒绝服务是可以作为法律诉讼理由的。
- 即使循环自身不是什么问题,爬虫也是在获取大量重复的页面[通常被称为”dups”(重复),以便与”loops”(循环)押韵]。爬虫应用程序会被重复的内容所充斥,这样应用程序就会变得毫无用处。返回数百份完全相同页面的因特网搜索引擎就是一个这样的例子。
记录曾经到过哪些地方
记录曾经到过哪些地方并不总是一件容易的事。因特网上有数十亿个不同的Web页面,其中还不包括那些由动态网关产生的内容。如果要爬行世界范围内的一大块Web内容,就要做好访问数十亿URL的准备。记录下哪些URL已经访问过了是件很具挑战的事情。由于URL的数量巨大,所以,要使用复杂的数据结构以便快速判定哪些URL是曾经访问过的。数据结构在访问速度和内存使用方面都应该是非常高效的。数亿URL需要具备快速搜索结构,所以速度是很重要的。穷举搜索URL列表是根本不可能的。爬虫至少要用到搜索树或散列表,以快速判定某个URL是否被访问过。数亿URL还会占用大量的空间。
大规模Web爬虫对其访问过的地址进行管理时使用的一些有用的技术:
- 树和散列表:复杂的爬虫可能会用搜索树或散列表来记录已访问的URL。这些是加速URL查找的软件数据结构。
- 有损的存在位图:为了减小空间,一些大型爬虫会使用有损数据结构,比如存在位数组(presence bit array)。用一个散列函数将每个URL都转换成一个定长的数字,这个数字在数组中有个相关的”存在位”。爬行过一个URL时,就将相应的”存在位”置位。如果存在位已经置位了,爬虫就认为已经爬行过那个URL了。
- 检查点:一定要将已访问URL列表保存到硬盘上,以防爬虫程序崩溃。
- 分布式:随着Web的扩展,在一台计算机上通过单个爬虫来完成爬行就变得不太现实了。那台计算机可能没有足够的内存、磁盘空间、计算能力,或网络带宽来完成爬行任务。有些大型Web爬虫会使用爬虫”集群”,每个独立的计算机是一个爬虫,以汇接方式工作。为每个爬虫分配一个特定的URL”片”,由其负责爬行。这些爬虫配合工作,爬行整个Web。爬虫个体之间可能需要相互通信,来回传送URL,以覆盖出故障的对等实体的爬行范围,或协调其工作。
别名与爬虫环路
由于URL”别名”的存在,即使使用了正确的数据结构,有时也很难分辨出以前是否访问过某个页面。如果两个URL看起来不一样,但实际指向的是同一资源,就称这两个URL互为”别名”。
规范化URL
大多数Web爬虫都试图通过将URL”规范化”为标准格式来消除上面那些显而易见的别名。爬虫首先可先将每个URL都转化为规范化的格式,就可以消除大部分别名问题了。但如果不知道特定Web服务器的相关信息,爬虫就没什么好办法来避免别名问题了。URL规范化可以消除一些基本的语法别名,但爬虫还会遇到其他的、将URL转换为标准形式也无法消除的URL别名。
通过下列步骤将每个URL都转化为规范化的格式:
- 如果没有指定端口的话,就向主机名中添加”:80″。
- 将所有转义符”%xx”都转换成等价字符。
- 删除”#”标签。
特定Web服务器的相关信息:
- 爬虫需要知道Web服务器是否是大小写无关的才能避免别名问题。
- 爬虫需要知道Web服务器上这个目录下的索引页面配置才能知道是否是别名。
- 即使爬虫知道主机名和IP地址都指向同一台计算机,它也还要知道Web服务器是否配置为进行虚拟主机操作,才能知道这个URL是不是别名。
文件系统连接环路
文件系统中的符号连接会造成特定的潜在环路,因为它们会在目录层次深度有限的情况下,造成深度无限的假象。符号连接环路通常是由无心错误造成的,但也可能会恶意地为爬虫制造这样的陷阱。
动态虚拟Web空间
可能会有意创建一些复杂的循环来陷害那些无辜的、毫无戒备的爬虫。尤其是,发布一个看起来像普通文件,实际上却是网关应用程序的URL是很容易的。这个应用程序可以在传输中构造出包含了到同一服务器上虚构URL链接的HTML。请求这些虚构的URL时,服务器就会捏造出一个带有新的虚构URL的新HTML页面来。即使这个Web服务器实际上并不包含任何文件,它也可以通过无限虚拟的Web空间将爬虫带入”梦境”。更糟的是,每次的URL和HTML看起来都有很大的不同,爬虫很难检测到环路。更常见的情况是,可能会在无意中通过符号连接或动态内容构造出爬虫陷阱。比如,一个基于CGI的日历程序,它会生成一个月历和一个指向下个月的链接。真正的用户是不会不停地请求下个月的链接的,但不了解其内容的动态特性的爬虫可能会不断向这些资源发出无穷的请求。
避免循环和重复
没有什么简单明了的方式可以避免所有的环路。实际上,经过良好设计的爬虫中要包含一组试探方式,以避免环路的出现。总的说来,爬虫的自动化程度越高(人为的监管越少),越可能陷入麻烦之中。爬虫的实现者需要做一些取舍——这些试探方式有助于避免问题的出现,但你可能会终止扫描那些看起来可疑的有效内容,因此这种方式也是”有损失”的。爬行Web这样规模庞大的数据集时,好的爬虫探测法总是会不断改进其工作的。随着新的资源类型不断加入Web,它会随着时间的推移构建出一些新的规则,并采纳这些规则。好的规则总是在不断发展之中的。当受到错误爬虫影响的资源(服务器、网络带宽等)处于可管理状态,或者处于执行爬行工作的人的控制之下(比如在内部站点上)时,很多较小的、更具个性的爬虫就会绕开这些问题。这些爬虫更多的是依赖人类的监视来防止这些问题的 发生。
爬虫会遇到的各种危险的Web中,有些技术的使用可以使爬虫有更好的表现:
- 规范化URL:将URL转换为标准形式以避免语法上的别名。
- 广度优先的爬行:每次爬虫都有大量潜在的URL要去爬行。以广度优先的方式来调度URL去访问Web站点,就可以将环路的影响最小化。即使碰到了爬虫陷阱,也可以在回到环路中获取的下一个页面之前,从其他Web站点中获取成百上千的页面。如果采用深度优先方式,一头扎到单个站点中去,就可能会跳入环路,永远无法访问其他站点。
- 节流:限制一段时间内爬虫可以从一个Web站点获取的页面数量。如果爬虫跳进了一个环路,试图不断地访问某个站点的别名,也可以通过节流来限制重复的页面总数和对服务器的访问总数。
- 限制URL的大小:爬虫可能会拒绝爬行超出特定长度(通常是1KB)的URL。如果环路使URL的长度增加,长度限制就会最终终止这个环路。有些Web服务器在使用长URL时会失败,因此,被URL增长环路困住的爬虫会使某些Web服务器崩溃。这会让人错误地将爬虫当成发起拒绝服务攻击的攻击者。要小心,这种技术肯定会让你错过一些内容。现在很多站点都会用URL来管理用户的状态(比如,在一个页面引用的URL中存储用户ID)。用URL长度来限制爬虫可能会带来些麻烦;但如果每当请求的URL达到某个特定长度时,都记录一次错误的话,就可以为用户提供一种检查某特定站点上所发生情况的方法。
- URL/站点黑名单:维护一个与爬虫环路和陷阱相对应的已知站点及URL列表,然后像躲避瘟疫一样避开它们。发现新问题时,就将其加入黑名单。这就要求有人工进行干预。但现在很多大型爬虫产品都有某种形式的黑名单,用于避开某些存在固有问题或者有恶意的站点。还可以用黑名单来避开那些对爬行大惊小怪的站点。
- 模式检测:文件系统的符号连接和类似的错误配置所造成的环路会遵循某种模式;比如,URL会随着组件的复制逐渐增加。有些爬虫会将具有重复组件的URL当作潜在的环路,拒绝爬行带有多于两或三个重复组件的 URL。重复并不都是立即出现的。有些环路周期可能为2或其他间隔。有些爬虫会查找具有几种不同周期的重复模式。
- 内容指纹:一些更复杂的Web爬虫会使用指纹这种更直接的方式来检测重复。使用内容指纹的爬虫会获取页面内容中的字节,并计算出一个校验和(checksum)。这个校验和是页面内容的压缩表示形式。如果爬虫获取了一个页面,而此页面的校验和它曾经见过,它就不会再去爬行这个页面的链接了——如果爬虫以前见过页面的内容,它就已经爬行过页面上的链接了。必须对校验和函数进行选择,以求两个不同页面拥有相同校验和的几率非常低。MD5这样的报文摘要函数就常被用于指纹计算。有些Web服务器会在传输过程中对页面进行动态的修改,所以有时爬虫会在校验和的计算中忽略Web页面内容中的某些部分,比如那些嵌入的链接。而且,无论定制了什么页面内容的动态服务器端包含(比如添加日期、访问计数等)都可能会阻碍重复检测。
- 人工监视:Web就是一片荒野。勇敢的爬虫最终总会陷入一个采用任何技术都无能为力的困境。设计所有产品级爬虫时都要有诊断和日志功能,这样人类才能很方便地监视爬虫的进展,如果发生了什么不寻常的事情就可以很快收到警告。在某些情况下,愤怒的网民会给你发送一些无礼的邮件来提示你出了问题。
爬虫的HTTP
爬虫和所有其他HTTP客户端程序并没有什么区别。它们也要遵守HTTP规范中的规则。发出HTTP请求并将自己广播成”HTTP/1.1″客户端的爬虫也要使用正确的HTTP请求首部。很多爬虫都试图只实现请求它们所查找内容所需的最小HTTP集。这会引发一些问题;但短期内这种行为不会发生什么改变。结果就是,很多爬虫发出的都是”HTTP/1.0″请求,因为这个协议的要求很少。
识别请求首部
尽管爬虫倾向于只支持最小的HTTP集,但大部分爬虫确实实现并发送了一些识别首部——最值得一提的就是User-Agent首部。建议爬虫实现者们发送一些基本的首部信息,以通知各站点爬虫的能力、爬虫的标识符,以及它是从何处起源的。
在追踪错误爬虫的所有者,以及向服务器提供爬虫所能处理的内容类型时,这些信息都是很有用的。鼓励爬虫实现者们使用的基本识别首部包括如下内容:
- User-Agent:将发起请求的爬虫名字告知服务器。
- From:提供爬虫的用户/管理员的E-mail地址。
- Accept:告知服务器可以发送哪些媒体类型。这有助于确保爬虫只接收它感兴趣的内容(文本、图片等)。
- Referer:提供包含了当前请求URL的文档的URL。
虚拟主机
爬虫实现者要支持Host首部。随着虚拟主机的流行,请求中不包含Host首部的话,可能会使爬虫将错误的内容与一个特定的URL关联起来。因此,”HTTP/1.1″要求使用Host首部。在默认情况下,大多数服务器都被配置为提供一个特定的站点。因此,不包含Host首部的爬虫向提供两个站点的服务器发起请求时。
条件请求
尽量减少爬虫所要获取内容的数量通常是很有意义的。对因特网搜索引擎爬虫来说,需要下载的潜在页面有数十亿,所以,只在内容发生变化时才重新获取内容是很有意义的。有些爬虫实现了条件HTTP请求,它们会对时间戳或实体标签进行比较,看看它们最近获取的版本是否已经升级了。这与HTTP缓存查看已获取资源的本地副本是否有效的方法非常相似。
对响应的处理
很多爬虫的兴趣主要在于用简单的GET方法来获取所请求的内容,所以,一般不会在处理响应的方式上花费太多时间。但是,使用了某些HTTP特性(比如条件请求)的爬虫,以及那些想要更好地探索服务器,并与服务器进行交互的爬虫则要能够对各种不同类型的HTTP响应进行处理。
- 状态码:爬虫至少应该能够处理一些常见的,以及预期的状态码。所有爬虫都应该理解”200 OK”和”404 Not Found”这样的状态码。它们还应该能够根据响应的一般类别对它并不十分理解的状态码进行处理。
- 实体:除了HTTP首部所嵌的信息之外,爬虫也会在实体中查找信息。HTML元标签(比如元标签http-equiv),就是内容编写者用于嵌入资源附加信息的一种方式。服务器可能会为它所处理的内容提供一些首部,标签http-equiv为内容编写者提供了一种覆盖这些首部的方式(meta http-equiv=”Refresh” content=”1;URL=index.html”)。这个标签会指示接收者处理这个文档时,要当作其HTTP响应首部中有一个值为”1, URL=index.html”的”Refresh HTTP”首部。有些服务器实际上会在发送HTML页面之前先对其内容进行解析,并将http-equiv指令作为首部包含进去;有些服务器则不会。爬虫实现者可能会去扫描HTML文档的HEAD组件,以查找http-equiv信息。
User-Agent导向
Web管理员应该记住,会有很多的爬虫来访问它们的站点,因此要做好接收爬虫请求的准备。很多站点会为不同的用户代理进行内容优化,并尝试着对浏览器类型进行检测,以确保能够支持各种站点特性。这样的话,当实际的HTTP客户端根本不是浏览器,而是爬虫的时候,站点为爬虫提供的就会是出错页面而不是页面内容了。在某些搜索引擎上执行文本搜索,搜索短语”your browser does not support frames”(你的浏览器不支持框架),会生成一个包含那条短语的出错页面列表。站点管理员应该设计一个处理爬虫请求的策略。比如,它们可以为所有其他特性不太丰富的浏览器和爬虫开发一些页面,而不是将其内容限定在特定浏览器所支持的范围。至少,管理员应该知道爬虫是会访问其站点的,不应该在爬虫访问时感到猝不及防。
行为不当的爬虫
不守规矩的爬虫会造成很多严重问题:
- 失控爬虫:爬虫发起HTTP请求的速度要比在Web上冲浪的人类快得多,它们通常都运行在具有快速网络链路的高速计算机上。如果爬虫存在编程逻辑错误,或者陷入了环路之中,就可能会向Web服务器发出大量的负载——很可能会使服务器过载,并拒绝为任何其他人提供服务。所有的爬虫编写者都必须特别小心地设计一些保护措施,以避免失控的爬虫带来的危害。
- 失效的 URL:有些爬虫会去访问URL列表。这些列表可能很老了。如果一个Web站点对其内容进行了大量的修改,爬虫可能会对大量不存在的URL发起请求。这会激怒某些Web站点的管理员,他们不喜欢他们的错误日志中充满了对不存在文档的访问请求,也不希望提供出错页面的开销降低其Web服务器的处理能力。
- 很长的错误 URL:由于环路和编程错误的存在,爬虫可能会向Web站点请求一些很大的、无意义的URL。如果URL足够长的话,就会降低Web服务器的性能,使Web服务器的访问日志杂乱不堪,甚至会使一些比较脆弱的Web服务器崩溃。
- 爱打听的爬虫:有些爬虫可能会得到一些指向私有数据的URL,这样,通过因特网搜索引擎和其他应用程序就可以很方便地访问这些数据了。如果数据的所有者没有主动宣传这些Web页面,那么在最好的情况下,他只是会认为爬虫的发布行为惹人讨厌,而在最坏的情况下,则会认为这种行为是对隐私的侵犯。通常,发生这种情况是由于爬虫所跟踪的、指向”私有”内容的超链已经存在了(也就是说,这些内容并不像其所有者认为的那么隐密,或者其所有者忘记删除先前存在的超链了)。偶尔也会因为爬虫非常热衷于寻找某站点上的文档而出现这种情况,很可能就是在没有显式超链的情况下去获取某个目录的内容造成的。从Web上获取大量数据的爬虫的实现者们应该清楚,他们的爬虫很可能会在某些地方获得敏感的数据——站点的实现者不希望通过因特网能够访问到这些数据。这些敏感数据可能包含密码文件。很显然,一旦被指出,就应该有某种机制可以将这些数据丢弃(并从所有搜索索引或归档文件中将其删除),这是非常重要的。现在已知一些恶意使用搜索引擎和归档的用户会利用大型Web爬虫来查找内容——有些搜索引擎, 实际上会对它们爬行过的页面进行归档,这样,即使内容被删除了,在一段时间内还是可以找到并访问它。
- 动态网关访问:爬虫并不总是知道它们访问的是什么内容。爬虫可能会获取一个内容来自网关应用程序的URL。在这种情况下,获取的数据可能会有特殊的目的,计算的开销可能很高。很多Web站点管理员并不喜欢那些去请求网关文档的幼稚爬虫。
拒绝爬虫访问
爬虫社团能够理解爬虫访问Web站点时可能引发的问题。1994 年,人们提出了一项简单的自愿约束技术,可以将爬虫阻挡在不适合它的地方之外,并为网站管理员提供了一种能够更好地控制爬虫行为的机制。这个标准被称为”拒绝爬虫访问标准”,但通常只是根据存储访问控制信息的文件而将其称为”robots.txt”。”robots.txt”的思想很简单。所有Web服务器都可以在服务器的文档根目录中提供一个可选的、名为”robots.txt”的文件。这个文件包含的信息说明了爬虫可以访问服务器的哪些部分。如果爬虫遵循这个自愿约束标准,它会在访问那个站点的所有其他资源之前,从Web站点请求”robots.txt”文件。
拒绝爬虫访问标准
拒绝爬虫访问标准是一个临时标准。不同的厂商实现了这个标准的不同子集。但是,具备一些对爬虫访问Web站点的管理能力,即使并不完美,也总比一点儿都没有要好,而且大部分主要的生产厂商和搜索引擎爬虫都支持这个拒绝访问标准。现在大多数爬虫采用的都是标准v0.0或v1.0。版本v2.0要复杂得多,没有得到广泛的应用。
Web站点和robots.txt文件
如果一个Web站点有”robots.txt”文件,那么在访问这个Web站点上的任意URL之前,爬虫都必须获取它并对其进行处理。由主机名和端口号定义的整个Web站点上仅有一个”robots.txt”资源。如果这个站点是虚拟主机,每个虚拟的docroot都可以有一个不同的robots.txt文件,像所有其他文件一样。通常不能在Web站点上单独的子目录中安装”本地robots.txt文件”。管理员要负责创建一个聚合型”robots.txt”文件,用以描述Web站点上所有内容的拒绝访问规则。
- 获取robots.txt:爬虫会用HTTP的GET方法来获取”robots.txt”资源,就像获取Web服务器上所有其他资源一样。如果有”robots.txt”文件的话,服务器会将其放在一个”text/plain”主体中返回。如果服务器以”404 Not Found”HTTP状态码进行响应,爬虫就可以认为这个服务器上没有爬虫访问限制,它可以请求任意的文件。爬虫应该在From首部和User-Agent首部中传输标识信息,以帮助站点管理员对爬虫的访问进行跟踪,并在站点管理员要查询,或投诉的爬虫事件中提供一些联系信息。
响应码:很多Web站点都没有”robots.txt”资源,但爬虫并不知道这一点。它必须尝试着从每个站点上获取”robots.txt”资源。爬虫会根据对”robots.txt”检索的结果采取不同的行动。
- 如果服务器以一个成功状态(HTTP状态码2XX)为响应,爬虫就必须对内容进行解析,并使用排斥规则从那个站点上获取内容。
- 如果服务器响应说明资源并不存在(HTTP状态码404),爬虫就可以认为服务器没有激活任何排斥规则,对此站点的访问不受”robots.txt”的限制。
- 如果服务器响应说明有访问限制(HTTP状态码401或403),爬虫就应该认为对此站点的访问是完全受限的。
- 如果请求尝试的结果是临时故障(HTTP状态码503),爬虫就应该推迟对此站点的访问,直到可以获取该资源为止。
- 如果服务器响应说明是重定向(HTTP状态码3XX),爬虫就应该跟着重定向,直到找到资源为止。
robots.txt文件的格式
“robots.txt”文件采用了非常简单的,面向行的语法。”robots.txt”文件中有三种类型的行:空行、注释行和规则行。规则行看起来就像HTTP首部一样,用于模式匹配。”robots.txt”文件中的行可以从逻辑上划分成”记录”。每条记录都为一组特定的爬虫描述了一组排斥规则。通过这种方式,可以为不同的爬虫使用不同的排斥规则。每条记录中都包含了一组规则行,由一个空行或文件结束符终止。记录以一个或多个User-Agent行开始,说明哪些爬虫会受此记录的影响,后面跟着一些Disallow和Allow行,用来说明这些爬虫可以访问哪些URL。
此例显示了一个”robots.txt”文件,这个文件允许爬虫Slurp和Webcrawler访问除了private子目录下那些文件之外所有的文件。这个文件还会阻止所有其他爬虫访问那个站点上的任何内容。
# 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:
- User-Agent行:每个爬虫记录都以一个或多个下列形式的User-Agent行开始。在爬虫”HTTP GET”请求的User-Agent首部中发送(由爬虫实现者选择的)爬虫名。如果爬虫无法找到与其名字相匹配的User-Agent行,而且也无法找到通配的”User-Agent:*”行,就是没有记录与之匹配,访问不受限。
爬虫处理”robots.txt”文件时,它所遵循的记录必须符合下列规则之一:
- 第一个robot-name是爬虫名的大小写无关的子字符串;
- 第一个robot-name为“*”。
- Disallow和Allow行:Disallow和Allow行紧跟在爬虫排斥记录的User-Agent行之后。用来说明显式禁止或显式允许特定爬虫使用哪些URL路径。爬虫那个必须将期望访问的URL按序与排斥记录中所有的Disallow和Allow规则进行匹配。使用找到的第一个匹配项。如果没有找到匹配项,就说明允许使用这个URL。要使Allow/Disallow行与一个URL相匹配,规则路径就必须是URL路径大小写相关的前缀。
- Disallow/Allow 前缀匹配:前缀匹配通常都能很好地工作,但有几种情况下它的表达力却不够强。如果希望无论使用什么路径前缀,都不允许爬行一些特别的子目录,那”robots.txt”是无能为力的。
Disallow/Allow前缀匹配的一些细节:
- Disallow和Allow规则要求大小写相关的前缀匹配。(与User-Agent行不同)这里的”*”(星号)没什么特殊的含义,但空字符串可以起到通配符的效果。
- 在进行比较之前,要将规则路径或URL路径中所有”被转义”的字符(%XX)都反转为字节(除了正斜杠%2F之外,它必须严格匹配)。
- 如果规则路径为空字符串,就与所有内容都匹配。
其他有关robots.txt的知识
<p>解析 robots.txt 文件时还需遵循其他一些规则。</p>
- 随着规范的发展,”robots.txt”文件中可能会包含除了User-Agent、Disallow和Allow之外的其他字段。爬虫应该将所有它不理解的字段都忽略掉。
- 为了实现后向兼容,不能在中间断行。
- 注释可以出现在文件的任何地方;注释包括可选的空格,以及后面的注释符(#)、注释符后面的注释,直到行结束符为止。
- 0.0版的拒绝爬虫访问标准并不支持Allow行。有些爬虫只实现了0.0版的规范,因此会忽略Allow行。在这种情况下,爬虫的行为会比较保守,有些允许访问的URL它也不去获取。
缓存和robots.txt的过期
如果一个爬虫在每次访问文件之前都要重新获取”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”文件就没什么效果了,站点管理员会责怪爬虫管理员没有遵守拒绝爬虫访问标准。
搜索引擎
得到最广泛使用的Web爬虫都是因特网搜索引擎。因特网搜索引擎可以帮助用户找到世界范围内涉及任意主题的文档。现在Web上很多最流行的站点都是搜索引擎。很多Web用户将其作为起始点,它们会为用户提供宝贵的服务,帮助用户找到他们感兴趣的信息。Web爬虫为因特网搜索引擎提供信息,它们获取Web上的文档,并允许搜索引擎创建索引,用以说明哪些文档中有哪些词存在。搜索引擎是Web爬虫的主要来源。
大格局
Web发展的初期,搜索引擎就是一些相当简单的数据库,可以帮助用户在Web上定位文档。现在,Web上有数十亿可供访问的页面,搜索引擎已经成为因特网用户查找信息不可缺少的工具。它们在不断地发展,以应对Web庞大的规模,因此,现在已经变得相当复杂了。
面对数十亿的Web页面,和数百万要查找信息的用户,搜索引擎要用复杂的爬虫来获取这数十亿Web页面,还要使用复杂的查询引擎来处理数百万用户产生的查询负荷。产品级Web爬虫的任务,要获取搜索索引所需的页面,它要发出数十亿条HTTP请求。如果每条请求都要花半秒钟的时间(对有些服务器来说可能慢了,对另一些服务器来说可能快了)。如果请求是连续发出的,结果差不多是5700天!很显然,大型爬虫得更聪明一些,要对请求进行并行处理,并使用大量服务器来完成这项任务。但由于其规模庞大,爬行整个Web仍然是件十分艰巨的任务。
现代搜索引擎结构
现在的搜索引擎都构建了一些名为”全文索引”的复杂本地数据库,装载了全世界的Web页面,以及这些页面所包含的内容。这些索引就像Web上所有文档的卡片目录一样。搜索引擎爬虫会搜集Web页面,把它们带回家,并将其添加到全文索引中去。同时,搜索引擎用户会通过HotBot或Google这样的Web搜索网关对全文索引进行查询。Web页面总是在不断地发生变化,而且爬行一大块Web要花费很长的时间,所以全文索引充其量也就是Web的一个快照。
全文索引
全文索引就是一个数据库,给它一个单词,它可以立即提供包含那个单词的所有文档。创建了索引之后,就不需要对文档自身进行扫描了。
发布查询请求
用户向Web搜索引擎网关发布一条请求时,会填写一个HTML表单,他的浏览器会用一个HTTP GET或POST请求将这个表单发送给网关。网关程序对搜索请求进行解析,并将Web UI查询转换成搜索全文索引所需的表达式。
对结果进行排序,并提供查询结果
旦搜索引擎通过其索引得到了查询结果,网关应用程序会获取结果,并将其拼成结果页面提供给终端用户。很多Web页面都可能包含任意指定的单词,所以搜索引擎采用了一些很聪明的算法,尝试着对结果进行排名。为了将相关度最高的结果提供给用户,搜索引擎要知道应该按照什么顺序来提供结果列表中的文档。这被称为相关性排名(relevancy ranking)——这是对一系列搜索结果的评分和排序处理。为了更好地辅助这一进程,在爬行Web的过程中都会进行数据统计。比如,对指向指定页面的链接进行计数有助于判断其流行程度,还可以用此信息来衡量提供结果的顺序。算法、爬行中获取的辅助信息以及搜索引擎所使用的其他技巧都是保守最森严的秘密。
欺诈
在搜索请求得到的前几个结果中没有看到自己想要查找的内容时,用户通常会感到很沮丧,因此,查找站点时搜索结果的顺序是很重要的。在搜索管理员们认为能够最好地描述其站点功能的单词时,会有众多因素激励着这些管理员,努力使其站点排在靠近结果顶端的位置上,尤其是那些依赖于用户找到它们,并使用其服务的商业站点。这种对较好排列位置的期待引发了很多对搜索系统的博弈,也在搜索引擎的实现者和那些想方设法要将其站点列在突出位置的人之间引发了持久的拉锯战。很多管理员都列出了无数关键字(有些是毫不相关的),使用一些假冒页面,或者采用欺诈行为——甚至会用网关应用程序来生成一些在某些特定单词上可以更好地欺骗搜索引擎相关性算法的假冒页面。这么做的结果就是,搜索引擎和爬虫实现者们要不断地修改相关性算法,以便更有效地抓住这些欺诈者。