如何使用gevent和线程抓取和处理(cpu密集)成千上万的URL?

时间:2015-03-29 17:24:51

标签: python multithreading asynchronous urllib2 gevent

我一直在玩龙卷风,扭曲,gevent,格斗,以便在获取50k网址的过程中获得最佳性能。

我想要创建的过程:

  • 将所有网址解析为一组(避免重复)
  • 每个网址
  • :检查白名单redis数据库中是否存在网址(包含数百万个网址)
  • 使用gevent / other async libraries下载网址
  • 将获取的内容插入队列
  • 并行:用线程监听队列
  • 使用线程的进程(密集正则表达式)队列项
  • 将输出保存到MySQL DB
  • 为每个网址更新白名单redis db

我每天要处理数百万个网址,我开始实现这个但是遇到了一些问题;

首先,使用从异步爬虫获得的结果填充队列消耗大量内存 - 我需要解决它,这将是一个好习惯吗? 其次,我很难同步线程和gevent抓取工具,如何在用结果填充队列时异步下载和处理?

或者,如何将async-crawler与处理来自async-crawler的响应的线程代码同步?

谢谢!

1 个答案:

答案 0 :(得分:1)

gevent, twisted, asyncio should handle 50k urls just fine

为了避免消耗太多内存并同步下载和处理URL的进程,您可以在相应的队列上设置最大大小:如果下载过快;它会在queue.put()达到最大容量时阻止。

绿色线程对于并行正则表达式处理毫无用处。如果在正则表达式处理期间未释放GIL,那么使用真实OS线程的普通Python线程将无用。 re不会发布GIL。 regex模块可以在某些情况下释放GIL。

如果您使用re模块;您可能希望创建一个进程池而不是主机上进程数~cpus数的线程。

小心你如何使用MySQL,Redis(在一些使用场景中你可能需要绿色驱动程序)。