使用Eventlet和Python抓取网页的速度如何?
我正在用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 个回答
我们创建了一个转换代理服务,使用了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进行“猴子补丁”,使其本质上非常适合异步处理。