网络蜘蛛如何与Wget的蜘蛛不同?

Léo*_* 준영 7 open-source wget web-crawler

下一句话引起了我对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.
Run Code Online (Sandbox Code Playgroud)

我在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)
Run Code Online (Sandbox Code Playgroud)

我希望看到代码的差异,而不是抽象的.我喜欢代码示例.

网络蜘蛛如何与代码中的Wget蜘蛛不同

Yaa*_*lch 33

真正的蜘蛛是很多工作

为整个WWW编写蜘蛛是一项非常重要的任务 - 您必须关注许多"小细节",例如:

  • 每台蜘蛛计算机应该并行接收来自几千台服务器的数据,以便有效利用连接带宽.(异步套接字i/o).
  • 你需要几台并行蜘蛛的计算机,以便覆盖WWW上的大量信息(聚类;分割工作)
  • 您需要对蜘蛛网站保持礼貌:
    • 尊重robots.txt文件.
    • 不要太快地获取大量信息:这会使服务器过载.
    • 不要获取你真正不需要的文件(例如iso磁盘映像;用于软件下载的tgz软件包......).
  • 您必须处理cookie /会话ID:许多站点将唯一的会话ID附加到URL以识别客户端会话.每次到达站点时,都会获得一个新的会话ID和一个新的页面虚拟世界(具有相同的内容).由于这些问题,早期的搜索引擎忽略了动态内容.现代搜索引擎已经了解了问题是什么以及如何处理它们.
  • 您必须检测并忽略麻烦的数据:连接提供看似无限量的数据或连接太慢而无法完成.
  • 除了以下链接,您可能还需要解析站点地图以获取页面的URL.
  • 您可能希望评估哪些信息对您很重要,并且经常更改以比其他页面更频繁地刷新.注意:整个WWW的蜘蛛会收到大量数据 - 你需要为这个带宽付费.您可能希望使用HTTP HEAD请求来猜测页面是否已更改.
  • 除了接收之外,您还希望处理信息并存储它.Google会为每个单词列出包含它的页面的索引.您可能需要单独的存储计算机和基础结构来连接它们.传统的关系数据库不能满足存储/索引整个WWW的数据量和性能要求.

这是很多工作.但是如果你的目标比阅读整个WWW更适度,你可以跳过一些部分.如果你只是想下载一个维基等的副本,你可以看到wget的规格.

注意:如果你不相信这么多工作,你可能想了解谷歌如何重新发明大多数计算轮(在基本的Linux内核之上)来构建好的蜘蛛.即使你削减了很多角落,也需要做很多工作.

让我在三点上补充几点技术评论

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

您可以在并行进程或线程中运行多个spider程序.但是,您需要大约5000-10000个并行连接才能充分利用您的网络连接.并行处理/线程数量过多会产生过多的开销.

更好的解决方案是异步输入/输出:通过以非阻塞模式打开套接字并使用epoll或select来处理已接收数据的那些连接,在一个线程中处理大约1000个并行连接.从Linux内核2.4开始,Linux在后续版本中对可伸缩性(我还建议您研究内存映射文件)提供了极好的支持.

注意:使用异步I/O有助于比使用"快语"更多:这是更好地编写用Perl编写的,而不是如果你这样做是正确的,你可以运行C语言编写的1000个进程1000个连接的epoll的驱动程序使用perl编写的进程使100Mb连接饱和.

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

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

在多个服务器上分配工作

一台计算机跟不上整个WWW.您需要在多个服务器上分配您的工作并在它们之间交换信息.我建议为每个服务器分配一些"域名范围":保留域名的中央数据库,并引用蜘蛛计算机.

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

如果您在每台蜘蛛计算机上保留等待获取的URL队列,则不会出现性能瓶颈.但实现这一点需要相当多的编程.

阅读标准

我提到了几个标准(HTTP/1.x,Robots.txt,Cookies).花点时间阅读并实施它们.如果您只是关注您知道的网站示例,您将犯错误(忘记与您的样本无关的标准部分)并为使用这些附加功能的网站带来麻烦.

阅读HTTP/1.1标准文档很痛苦.但所有的小细节都加入了它,因为有人真的需要那些细节,现在就用它了.

  • 我没有在这个答案中看到它,但也许这包括在内:如果我没有弄错,'wget'也有所不同,因为它*不会*'下载/存储内容而'蜘蛛',而一般的网络蜘蛛收集*至少*一些关于它所见过的页面的元数据.我错了吗? (2认同)