【发布时间】:2013-01-12 07:33:57
【问题描述】:
我正在使用金字塔构建网站,我想从其他网站获取一些数据。因为urlopen 可能有 50+ 次调用,所以我想使用 gevent 来加快速度。
这是我到目前为止使用 gevent 得到的结果:
import urllib2
from gevent import monkey; monkey.patch_all()
from gevent import pool
gpool = gevent.pool.Pool()
def load_page(url):
response = urllib2.urlopen(url)
html = response.read()
response.close()
return html
def load_pages(urls):
return gpool.map(load_page, urls)
运行pserve development.ini --reload 给出:
NotImplementedError: gevent is only usable from a single thread.
我已经读到我需要先进行猴子补丁,但我不确定在哪里合适。另外,这是特定于 pserve 的问题吗?当我搬到mod_wsgi 时,我需要重新解决这个问题吗?或者有没有办法在没有 gevent 的情况下处理这个用例(只是 urlopen)?我已经看到了针对 requests 的建议,但我在文档中找不到获取多个页面的示例。
更新 1:
我也试过this SO question的eventlet(几乎是直接从这个eventletexample复制过来的):
import eventlet
from eventlet.green import urllib2
def fetch(url):
return urllib2.urlopen(url).read()
def fetch_multiple(urls):
pool = eventlet.GreenPool()
return pool.imap(fetch, urls)
但是,当我拨打fetch_multiple 时,我收到的是TypeError: request() got an unexpected keyword argument 'return_response'
更新 2:
上一次更新中的TypeError 可能来自之前尝试使用 gevent 进行猴子补丁并且未正确重新启动 pserve。一旦我重新启动一切,它就可以正常工作。经验教训。
【问题讨论】:
-
对于您的
eventlet代码……get_html来自哪里? -
抱歉,应该是
fetch。已更新。 -
好吧,我就是这么想的。无论如何,IIRC,
eventlet在这种情况下所做的是接管当前线程以运行 greenlets,直到池完成。我认为无论如何你最好分派到一个greenlet线程,即使这确实有效。但是,如果这可行,并且您想使用它,我想这可能是eventlet对您而言优于gevent的优势。 -
对,我希望它能做到这一点,但我得到了
request() got an unexpected keyword argument 'return_response'。我尝试添加一个 pool.waitall() 以防返回地图是问题,但没有运气。 -
其实我只是尝试重新启动整个堆栈,效果很好。当 pserve 重新启动所有东西时,一定是猴子修补某个地方没有被清除,这一直是垃圾。感谢您的帮助!
标签: python pyramid gevent urlopen