Python 从Eventlet GreenPile对象检索数据,可能与迭代器相关

Python 从Eventlet GreenPile对象检索数据,可能与迭代器相关,python,iterator,eventlet,Python,Iterator,Eventlet,我目前正在修改我不久前制作的一个简单监控脚本,基本上: 建立一个字典列表,其中包括 网址 响应所需的时间(默认设置为无) 它发送回的数据(默认设置为无) 从列表中查询(获取)每个URL,并用相关数据填充“时间”和“数据”字段 将结果存储在数据库中 该脚本过去工作正常,但随着要监视的URL列表的增加,完成所有查询所需的时间对我来说已经太长了 我的解决方案是修改脚本以并发方式获取URL。为了做到这一点,我选择使用它,因为从文档中可以看出,它几乎完全符合我的要求 问题是,由于我的URL列表包含字典

我目前正在修改我不久前制作的一个简单监控脚本,基本上:

建立一个字典列表,其中包括

  • 网址
  • 响应所需的时间(默认设置为无)
  • 它发送回的数据(默认设置为无)
从列表中查询(获取)每个URL,并用相关数据填充“时间”和“数据”字段

将结果存储在数据库中

该脚本过去工作正常,但随着要监视的URL列表的增加,完成所有查询所需的时间对我来说已经太长了

我的解决方案是修改脚本以并发方式获取URL。为了做到这一点,我选择使用它,因为从文档中可以看出,它几乎完全符合我的要求

问题是,由于我的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
是一个iterable,所以我可以遍历它,但我不能通过索引访问它的内容,对吗

那么,我如何(可能吗?)直接填写我的
url
列表?另一个解决方案是建立一个url的“平面”列表,另一个包含url、响应时间和数据的列表,并在第一个列表上使用
pool.imap()
,然后用它填充第二个列表,但我宁愿保留我的字典列表


*我最多只能发布3个与此帐户的链接,请查看eventlet文档中的“设计模式-调度模式”页面。

您可以迭代
绿桩
,但您需要从
获取
中返回一些内容,这样您就不仅仅有了响应。我修改了示例,以便
fetch
返回一个元组,该元组是url和响应主体

URL
变量现在是URL(字符串)到数据(无或字符串)的dict。在
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))