您好,我正在开发一个Web抓取工具,并且在特定的网站中使用,该网站有很多url,可能超过1.000.000,并且要进行报废并获取信息,我具有以下架构
用于存储已访问站点的集合,以及用于获取未访问站点的集合。
为了报废网站,我使用的线程数限制为2000。
此体系结构的内存大小有问题,并且永远无法完成,因为程序会使用url填充内存
在将URL放入未访问的站点之前,我首先检查这些站点是否已被访问,如果访问了该站点,则我将永远不会存储在未访问的站点中。
为此,我正在使用python,我认为也许更好的方法是将所有站点存储在数据库中,但是我认为这样做可能会很慢
我可以解决部分问题,将所有访问过的URL集存储在sqlite之类的数据库中,但是问题是未访问的url集太大并填满了所有内存
是否有关于通过其他工具,语言体系结构等来改进这一点的想法?
谢谢
答案 0 :(得分:1)
起初,我从来没有使用Python来抓取页面。我喜欢的语言是c#。但是python应该不错,或者更好。
好的,您发现的第一件事很重要。仅对您的内存进行操作将无法正常工作。实施一种在硬盘上工作的方法很重要。如果您只想处理内存,请考虑页面的大小。
我认为,您已经拥有用于爬网/爬网的最佳(或良好)架构。您需要某种列表,代表您已经访问过的URL,以及另一个列表,您可以在其中存储找到的新URL。只有两个列表是您最简单的选择。因为这意味着您没有在爬网中实施某种策略。如果您不需要那样的东西,那就好。但是请考虑一下,因为这样可以优化内存的使用。因此,您应该寻找诸如深度爬行和广泛爬行之类的东西。或递归爬网。将每个分支表示为自己的列表或数组的维。
此外,将您未访问的网址也存储在数据库中又是什么问题?因为您只需要在每个线程上。如果您将它放入db的问题是事实,它可能需要花一些时间来浏览它,那么您应该考虑为页面的每个部分使用多个表。
这意味着,您可以为url中的每个子字符串使用一个表:
wwww.example.com /
wwww.example.com/contact /
wwww.example.com/download /
wwww.example.com/content /
wwww.example.com/support /
wwww.example.com/news /
因此,如果您的网址是:“ wwww.example.com/download/sweetcats/”,则应将其放在wwww.example.com/download/表中。 如果您拥有一组网址,则必须首先查看正确的表。然后,您可以在桌子上滑动。
最后,我只有一个问题。为什么不使用已经支持这些功能的库或框架?我认为应该有一些适用于python的东西。
答案 1 :(得分:1)
2000个线程过多。甚至1个也可能太多。您的刮板可能会被视为DOS(拒绝服务)附件,并且您的IP地址将被阻止。
即使被允许,2000个线程也太多。您将在某个地方遇到瓶颈,并且该阻塞点可能会导致速度变慢,而如果您进行了一些合理的线程化,则可能会变慢。建议尝试10。一种查看方式-每个线程都会在获取URL(网络密集型)和处理URL(CPU密集型)之间翻转。因此,CPU数量的2倍是另一个可能的限制。
您需要一个数据库。这将使您退出并重新启动该过程。更重要的是,它可以让您修复错误并发布新的搜寻器,而不必丢弃所有已废弃的信息。
数据库将不是最慢的部分。主要步骤:
(我是在多年前这样做的。我有一台0.5GB的微型计算机。经过大约一百万次分析页面后我退出了。仍然有大约一百万页等待扫描。而且,是的,我被指控遭受DOS攻击。)