使用Eventlet和Python抓取网页的速度如何?

3 投票
1 回答
1275 浏览
提问于 2025-04-16 16:07

我正在用Python写一个相对简单的爬虫,但我想使用异步网络库,这样可以同时抓取多个网页。我在他们的页面上看到了示例,但当我用相同的逻辑去处理大约1000到2000个网址时,性能却变得很慢。(大多数网址来自不同的域名,我已经把它们打乱了顺序。) 那么,使用Eventlet抓取这么多页面的最快方法是什么?我能达到什么样的速度?(比如每秒抓取多少个网页)

下面是一个示例:


urls = ["http://www.google.com/intl/en_ALL/images/logo.gif",
     "https://wiki.secondlife.com/w/images/secondlife.jpg",
     "http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif"]

import eventlet
from eventlet.green import urllib2

def fetch(url):

  return urllib2.urlopen(url).read()

pool = eventlet.GreenPool()

for body in pool.imap(fetch, urls):
  print "got body", len(body)

1 个回答

2

我们创建了一个转换代理服务,使用了Spawning这个网络服务器。Spawning内部使用了事件处理技术。这个服务的目的是为了让旧的XML接口能够被手机应用(比如iPhone、Android等)使用。

http://pypi.python.org/pypi/Spawning/

1) 服务器调用了一个后端服务,这个服务会输出XML格式的数据,使用的是urllib这个库。

2) 然后,Python读取这个XML,把它转换成JSON格式。我们使用了lxml来解析XML,使用了simplejson这个库(它有一个用C语言编写的扩展)来输出JSON。

3) 最后生成的JSON数据会发送给客户端。

使用事件处理技术后,性能非常棒,能够达到每秒超过1000个请求,在一个有8个虚拟核心的服务器上运行。性能非常稳定,没有错误,延迟也很低。我们在进程和每个进程的线程数量之间做了一些平衡,最终使用了大约12个进程,每个进程有20到50个线程。

我们还测试了Twisted和它的异步页面获取方法。使用Twisted时,我们的性能只有每秒200个请求,之后就开始出现很多错误。而且使用Twisted时,延迟也迅速增加,导致这种方法不太可行。

性能是通过复杂的JMeter脚本来测量的,这些脚本会做一些复杂的操作,比如身份验证等。

我认为关键在于Spawning如何对urllib进行“猴子补丁”,使其本质上非常适合异步处理。

撰写回答