【问题标题】:What is the best option to thread in a spider?穿入蜘蛛的最佳选择是什么?
【发布时间】:2014-10-02 15:13:31
【问题描述】:

我用 Python 写了一个爬虫脚本,它工作得很好。但是,完成需要很长时间(超过 9 小时,具体取决于站点有多少链接)。

我想在其中实现线程化以缩短时间,但我无法确定哪个部分最适合线程化。乍一看,我会创建线程来获取每个页面的页面内容,然后锁定visited_urlsto_visit_urls 数组以确保所有内容都使用相同的列表。

但似乎它可能花费最多的时间检查visited_urlsto_visit_urls 数组中的重复项,那么以这种方式进行线程化真的可以为我节省那么多时间吗?有没有更好的方法让我的蜘蛛穿线?

【问题讨论】:

  • 如果您已经对代码进行了概要分析,并且在成员资格检查上花费了那么多时间,那么您可能正在使用 list 来进行 visited_urlsto_visit_urls 的 O(n) 查找。尝试改用 set,它有 O(1) 次查找。
  • 我没有分析我的代码,我只是有一个感觉。 :D

标签: python multithreading web-crawler


【解决方案1】:

您应该使用 grequests,它是请求的异步版本,可让您一次抓取多个 url,从而显着提高吞吐量。如果您遍历您的网址并处理子列表,这将非常有效。至于重复项,只需将列表转换为集合并返回即可将其删除,因为集合本质上不支持重复项。

urls = [...]
reqs = [grequests.get(x) for x in urls]
resp = grequests.map(reqs)

https://github.com/kennethreitz/grequests

【讨论】:

  • 我感觉转换为 set 需要 O(n^2) 才能删除所有重复项,不是吗?这比我目前用来保证我要添加的项目不存在的 O(n) 效率要低得多。不过我不确定,也无法在任何地方找到该信息...
  • “...不已经存在在列表中”,这就是我的意思。
  • 您确定您的瓶颈不是网络吞吐量吗?如果您的网络速度比您的计算速度更快,我会感到非常惊讶。另外,您为什么要使用两个列表而不是仅迭代一个?此外,如果您在启动时进行了一次设置转换然后迭代结果,我怀疑您会看到显着的性能下降。
  • 这很好,我可以从一开始就使用集合而不是列表。网络吞吐量很可能是最大的瓶颈……如果可以的话,我只是想加快其他领域的速度。我使用了两个列表,因为一个跟踪它访问的 URL,一个跟踪它尚未访问的 URL。两者都很重要,我不确定我是否知道如何在不跟踪这两个数据的情况下对网站进行完整的爬虫。
  • 为什么你需要跟踪那些你没去过的人?迭代一个事物可以保证您与每个元素进行交互。
猜你喜欢
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 2023-03-03
相关资源
最近更新 更多