我目前正在修改我前段时间制作的一个简单的监控脚本,它基本上是:
构建一个字典列表,其中包含
- 网站网址
- 响应时间(默认设置为无)
- 它返回的数据(默认设置为无)
查询 (GET) 列表中的每个 URL,并用相关数据填充“时间”和“数据”字段。
将结果存储在数据库中。
该脚本过去工作正常,但随着要监视的 URL 列表的增加,完成所有查询所需的时间对我来说变得太长了。
我的解决方案是修改脚本以并发方式获取 URL。为此,我选择使用 eventlet , 因为 this example文档中的内容几乎完全符合我的要求。
要注意的是,因为我的 URL 列表包含字典,所以我不能使用 pool.imap()
来遍历我的列表。 (据我所知)
Eventlet 文档有另一个类似的示例*,它使用 GreenPile 对象生成作业,似乎我可以使用它来启动我的 URL 获取功能,但我似乎无法检索该线程的结果。
这是我的测试代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import eventlet
from eventlet.green import urllib2
urls = [{'url': 'http://www.google.com/intl/en_ALL/images/logo.gif', 'data': None},
{'url': 'http://www.google.com', 'data': None}]
def fetch(url):
return urllib2.urlopen(url).read()
pool = eventlet.GreenPool()
pile = eventlet.GreenPile(pool)
for url in urls:
pile.spawn(fetch, url['url']) #can I get the return of the function here?
#or
for url in urls:
url['data'] = ??? #How do I get my data back?
#Eventlet's documentation way
data = "\n".join(pile)
据我所知,pile
是一个可迭代对象,因此我可以遍历它,但我无法通过索引访问它的内容,这是否正确?
那么,我如何(可能?)直接填写我的 urls
列表?另一种解决方案可以是构建一个“扁平”的 url 列表,另一个包含 url、响应时间和数据的列表,并在第一个列表上使用 pool.imap()
并用它填充第二个列表,但是我宁愿保留我的词典列表。
*我不能使用此帐户发布超过 3 个链接,请参阅 eventlet 文档中的“设计模式 - 调度模式”页面。
最佳答案
您可以遍历 GreenPile
,但您需要从 fetch
中返回一些内容,这样您得到的不仅仅是响应。我修改了示例,以便 fetch
返回一个元组,即 url 和响应主体。
urls
变量现在是 urls(string) 到数据(None 或 string)的字典。继续迭代 GreenPile
,直到没有更多任务为止。迭代应该在调用 spawn
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import eventlet
from eventlet.green import urllib2
#Change to map urls to the data found at them
urls = {'http://www.google.com/intl/en_ALL/images/logo.gif': None,
'http://www.google.com' :None}
def fetch(url):
#return the url and the response
return (url, urllib2.urlopen(url).read())
pool = eventlet.GreenPool()
pile = eventlet.GreenPile(pool)
for url in urls.iterkeys():
pile.spawn(fetch, url) #can I get the return of the function here? - No
for url,response in pile:
#stick it back into the dict
urls[url] = response
for k,v in urls.iteritems():
print '%s - %d bytes' % (k,len(v))
关于python - 从 Eventlet GreenPile 对象中检索数据,可能与迭代器相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17142938/