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编写蜘蛛是一项非常重要的任务 - 您必须关注许多"小细节",例如:
这是很多工作.但是如果你的目标比阅读整个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标准文档很痛苦.但所有的小细节都加入了它,因为有人真的需要那些细节,现在就用它了.