2009-04-17 82 views
7

接下来的一句话引起了我的眼睛在Wget的手册Web蜘蛛与Wget的蜘蛛有什么不同?

wget --spider --force-html -i bookmarks.html 

This feature needs much more work for Wget to get close to the functionality of real web spiders. 

我找到相关的代码在wget的蜘蛛选项以下行。

src/ftp.c 
780:  /* If we're in spider mode, don't really retrieve anything. The 
784:  if (opt.spider) 
889: if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST))) 
1227:  if (!opt.spider) 
1239:  if (!opt.spider) 
1268:  else if (!opt.spider) 
1827:   if (opt.htmlify && !opt.spider) 

src/http.c 
64:#include "spider.h" 
2405: /* Skip preliminary HEAD request if we're not in spider mode AND 
2407: if (!opt.spider 
2428:  if (opt.spider && !got_head) 
2456:  /* Default document type is empty. However, if spider mode is 
2570:   * spider mode. */ 
2571:   else if (opt.spider) 
2661:    if (opt.spider) 

src/res.c 
543: int saved_sp_val = opt.spider; 
548: opt.spider  = false; 
551: opt.spider  = saved_sp_val; 

src/spider.c 
1:/* Keep track of visited URLs in spider mode. 
37:#include "spider.h" 
49:spider_cleanup (void) 

src/spider.h 
1:/* Declarations for spider.c 

src/recur.c 
52:#include "spider.h" 
279:  if (opt.spider) 
366:    || opt.spider /* opt.recursive is implicitely true */ 
370:    (otherwise unneeded because of --spider or rejected by -R) 
375:     (opt.spider ? "--spider" : 
378:      (opt.delete_after || opt.spider 
440:  if (opt.spider) 

src/options.h 
62: bool spider;   /* Is Wget in spider mode? */ 

src/init.c 
238: { "spider",   &opt.spider,   cmd_boolean }, 

src/main.c 
56:#include "spider.h" 
238: { "spider", 0, OPT_BOOLEAN, "spider", -1 }, 
435:  --spider     don't download anything.\n"), 
1045: if (opt.recursive && opt.spider) 

我想看看代码中的差异,而不是抽象的。我喜欢代码示例。

怎么办网络蜘蛛不同于Wget的在码蜘蛛

回答

33

一个真正的蜘蛛是很多工作

编写整个WWW蜘蛛是一项艰巨的任务---你必须要对多的“小细节”,如护理:

  • 每台蜘蛛计算机都应该从几千台服务器并行接收数据,以便有效利用连接带宽。 (异步套接字I/O)。
  • 你需要一个并行蜘蛛为了掩盖对WWW的大量信息的几台电脑;
  • 你需要礼貌的爬行网站(集群分区的工作):
    • 尊重robots.txt文件。
    • 不要太快地获取大量信息:这会使服务器负载过重。
    • 不要取,你真的不需要的文件(例如ISO磁盘映像; tgz包软件下载...)。
  • 您必须处理cookies/session ids:许多站点会将唯一的会话id附加到URL以识别客户端会话。每次到达该网站时,都会得到一个新的会话ID和一个新的网页虚拟世界(具有相同的内容)。由于这样的问题,早期的搜索引擎忽略了动态内容。现代搜索引擎已经知道问题是什么以及如何处理它们。
  • 你必须检测和忽略麻烦的数据:即提供对完成太慢数据或连接的无穷尽的连接。
  • 除了以下链接,你可能要解析sitemaps得到的网页的URL。
  • 您可能要评估哪些信息是你和重要的变化比其他网页更频繁地频繁被刷新。注意:整个WWW的蜘蛛会收到大量的数据 - 您需要为该带宽付费。您可能想要使用HTTP HEAD请求来猜测页面是否已更改。
  • 除了接收,你想处理信息并存储它。 Google会建立索引,为每个单词列出包含它的页面。您可能需要单独的存储计算机和基础设施来连接它们。传统的关系数据库不能满足存储/索引整个WWW的数据量和性能要求。

这是一个大量的工作。但是如果你的目标比阅读整个WWW更温和,你可以跳过一些部分。如果你只是想下载一个wiki的副本等,你可以看看wget的规格。

注意:如果您不相信这么做太过成功,您可能需要阅读Google如何重新发明大部分计算机轮子(在基本Linux内核之上)来构建优秀的蜘蛛。即使你削减了很多角落,这也是很多工作。

让我三点

添加一些新的技术的话

并行连接/异步套接字通信

你可以并行运行的进程或线程数蜘蛛程序。但是,为了充分利用您的网络连接,您需要大约5000-10000个并行连接。并行进程/线程的这种数量会产生太多的开销。

更好的解决方案是异步输入/输出:通过在非阻塞模式下打开的套接字和使用epoll的或选择以处理只在那些已收到数据连接在一个单一的线程化处理约1000并行连接。自Linux内核2.4以来,Linux对可扩展性(我还建议您研究内存映射文件)的优秀支持在后续版本中不断得到改进。

注意:使用异步I/O比使用“快速语言”更有帮助:最好为用Perl编写的1000个连接编写一个epoll驱动的进程,而不是运行1000个用C编写的进程。如果你这样做对,你可以使用perl编写的进程饱和一个100Mb的连接。

从原来的答案: 这种方法的缺点是,你必须自己实现异步形式(我不知道,这是否可重新使用的库)的HTTP规范。使用比现代HTTP/1.1协议简单的HTTP/1.0协议更容易。无论如何,您可能无法从普通浏览器的HTTP/1.1的优点中受益,所以这可能是节省一些开发成本的好地方。

五年后编辑: 今天,有很多免费/开源技术可以帮助您完成这项工作。我个人喜欢node.js的异步http implementation ---它为您节省了上述原始段落中提到的所有工作。当然,今天也有很多模块可供其他组件在您的蜘蛛中使用。但请注意,第三方模块的质量可能差异很大。你必须检查你使用的任何东西。 [老龄问题:]最近,我写了一个使用node.js的蜘蛛,我发现npm模块的可靠性,用于链接和数据提取的HTML处理不足。对于这份工作,我将这个处理“外包”到用另一种编程语言编写的过程。但事情很快发生变化,你的时间阅读本评论,这个问题可能已经是过去的事了......

分区在数台服务器的工作

一台计算机无法跟上蜘蛛整个WWW。您需要将您的工作分配到多个服务器并在它们之间交换信息。我建议为每个服务器分配一定的“域名范围”:将域名的中央数据库与参考蜘蛛计算机保持一致。

从接收到的网页中批量提取URL:根据其域名进行排序;删除重复项并将它们发送给负责任的蜘蛛计算机。在该计算机上,保留已获取的URL索引并获取剩余的URL。

如果您在每台蜘蛛计算机上等待提取URL的队列,则不会有性能瓶颈。但是实现这一点需要很多编程。

阅读标准

我提到的几个标准(HTTP/1.x中,robots.txt的,饼干)。花点时间阅读并实施它们。如果您只是遵循您知道的网站示例,则会犯错误(忘记标准中与您的示例无关的部分内容),并为使用这些附加功能的网站带来麻烦。

阅读HTTP/1.1标准文档是一件痛苦的事情。但是所有的细节都被添加到了它中,因为有人真的需要那些细节并且现在使用它。

+0

写得很好,并说明是一个真正的网络蜘蛛的挑战,但我认为这个问题是指爬行“一个”网站,而不是整个互联网,可以做得比网络蜘蛛更好,没有太多的努力。 – 2009-05-13 19:59:29

4

我不确定这个评论的原始作者究竟是指什么,但我可以猜测wget作为一个蜘蛛很慢,因为它似乎只使用一个单一的执行线程(至少通过你所拥有的示出)。

诸如heritrix之类的“真实”蜘蛛使用大量的并行性和技巧来优化爬行速度,同时对他们爬行的网站很好。这通常意味着以每秒1次的速度限制访问一个站点,同时抓取多个网站。

再次,这只是一个猜测,根据我所了解的蜘蛛的一般情况以及您在此发布的内容。

2

不幸的是,许多比较知名的'真实'网络蜘蛛是封闭的,实际上是封闭的二进制。但是有一些基本技巧wget缺失:

  • 并行性;你将永远无法跟上整个网络而无需一次检索多个页面
  • 优先化;有些页面比其他页面更重要蜘蛛
  • 限速;如果您尽可能快地拉下页面,您将很快被禁止
  • 保存到本地文件系统以外的其他位置; Web足够大,不适合单个目录树
  • 定期重新检查页面而不重新启动整个过程;在实践中,你需要一个真正的蜘蛛来重新检查经常更新的“重要”页面,而不那么有趣的页面可能会持续数月。

也有各种其他输入可以使用,如站点地图等。需要指出的是,wget并不是为了捕捉整个网络而设计的,它不是一个可以在小代码示例中捕获的东西,因为这是整个技术被使用的问题,而不是任何一个小子程序都是错误的为任务。

1

我不打算详细介绍如何蜘蛛互联网,我认为wget评论是关于蜘蛛网站,这仍然是一个严峻的挑战。

  • 当你需要弄清楚什么时候停止,不进入递归蜘蛛抓取,只是因为URL变了样日期= 1/1/1900年到1900年1月2日等
  • 更大的挑战整理URL重写(我不知道谷歌或任何其他人如何处理这个)。抓取足够但不太多的挑战是非常大的挑战。以及如何使用一些随机参数和内容中的随机更改自动识别URL重写?
  • 您需要解析的Flash/JavaScript的至少到一定程度
  • 你需要考虑像基地标签一些疯狂的HTTP问题。即使解析HTML也不容易,因为大多数网站不是XHTML,浏览器在语法上非常灵活。

我不知道在wget中实现或考虑了多少这些,但您可能想看看httrack以了解此任务的挑战。

我很想给你一些代码示例,但这是大任务和一个体面的蜘蛛将约为5000位本地没有第三方库

+他们中的一些已经被@亚科夫 - 嗝解释,所以我不打算再键入它们