"in"的有效替代方案

dan*_*nem 4 python memory optimization list

我正在编写一个Web爬虫,其最终目标是创建爬虫所采用的路径的映射.虽然我不清楚其他的,以及绝大多数更好的爬行器下拉页面,但我的时钟大约每分钟2,000页.

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

for href in tempUrl:
    ...
    if href not in urls:
         collect(href,parent,depth+1)
Run Code Online (Sandbox Code Playgroud)

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

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

我认为减小每个条目的大小可能会有所帮助,所以我不是追加整个url,而是将前两个和最后一个附加到每个url的字符作为字符串.然而,这并没有帮助.

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

谢谢您的帮助

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

Bil*_*nch 15

也许你可以使用a set而不是a list到目前为止你看到的网址.

  • @Pete,是的 - 测试集合和dicts中的成员资格是O(1),在列表和元组中,O(n)在列表/元组的长度中.所以对于长列表/元组,它会产生_huge_差异.(+1顺便说一句.) (2认同)

Nou*_*him 7

只需将"已爬网URL列表"替换为" 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
Run Code Online (Sandbox Code Playgroud)