“in”的有效替代方案

时间:2011-06-28 16:14:45

标签: python list optimization memory

我正在编写一个网络抓取工具,其最终目标是创建抓取工具所采用路径的地图。虽然我不知道其他什么比率,而且绝对是更好的爬行器下拉页面,我的时钟大约每分钟2,000页。

爬虫使用递归回溯算法,我将其限制在15的深度。 此外,为了防止我的爬虫无休止地重新访问页面,它将它访问过的每个页面的URL存储在列表中,并检查该列表以查找下一个候选URL。

for href in tempUrl:
    ...
    if href not in urls:
         collect(href,parent,depth+1)

这种方法在拉下约300,000页时似乎成了一个问题。此时,爬虫平均每分钟计时500页。

所以我的问题是,在提高效率的同时实现相同功能的另一种方法是什么。

我认为减小每个条目的大小可能会有所帮助,因此我不会追加整个网址,而是将每个网址的前两个和最后一个字符追加为字符串。然而,这并没有帮助。

有没有办法用套装或其他东西做到这一点?

感谢您的帮助

编辑:作为旁注,我的程序还没有多线程。在我开始学习线程之前,我想我应该解决这个瓶颈。

4 个答案:

答案 0 :(得分:14)

也许你可以使用set代替list来查看到目前为止看到的网址。

答案 1 :(得分:7)

只需将“已抓取的网址列表”替换为“set已抓取的网址”。集合已针对随机访问进行了优化(使用字典使用的相同哈希算法)并且它们很多使用线性搜索完成列表的查找操作,因此速度不是很快。您不需要更改执行查找的实际代码。

检查一下。

In [3]: timeit.timeit("500 in t", "t = list(range(1000))")
Out[3]: 10.020853042602539

In [4]: timeit.timeit("500 in t", "t = set(range(1000))")
Out[4]: 0.1159818172454834

答案 2 :(得分:3)

我有类似的问题。结束了内存与时间的各种方法(列表/文件/集/ sqlite)的分析。看到这2篇文章。 最后sqlite是最好的选择。您还可以使用url hash来缩小大小

Searching for a string in a large text file - profiling various methods in python

sqlite database design with millions of 'url' strings - slow bulk import from csv

答案 3 :(得分:2)

使用带有网址的dict作为密钥(O(1)访问时间)。

但是一套也行。参见

http://wiki.python.org/moin/TimeComplexity