Eventlet的spawn不起作用。这么奇怪

时间:2014-07-13 12:08:49

标签: python spawn eventlet

****嗨,全部

我正在使用eventlet来实现网络爬虫。我的代码就像这样

import eventlet


urls = [
    "http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B",
    "http://www.google.com.hk",
    "http://www.baidu.com",
]



def fetch(url):
    print('entering fetch')
    body=urllib2.urlopen(url).read()
    print('body')


pool = eventlet.GreenPool(100)
for url in urls:
    pool.spawn(fetch,url)
    time.sleep(10)

但它没有输出任何内容,似乎fetch根本没有运行

BTW,pool.imap确实有效

发生了什么事?

我想要做的是:网址流淌,即。逐一。就像这样

While(True):
   url=getOneUrl() #get one url streamly
   pool.spawn(fetch,url) #fetch the url

但它也不起作用。

提前感谢....

2 个答案:

答案 0 :(得分:0)

根据eventlet实现,pool.imap代码将一直等到池中的所有greenthread完成工作,但pool.spawn将不会立即结束。

您可以尝试在脚本末尾添加一些等待或休眠。那些产生的greenthreads将执行你的功能。

pool.waitall()

eventlet.sleep(10)

实际上,在'for pool in pool.imap(fetch,urls)'中,它调用pool.imap并迭代结果。 pool.imap的调用不会调用等待函数,但是迭代会调用。

尝试在不迭代结果的情况下进行。没有迭代,它会立即以pool.spawn结束。

pool = eventlet.GreenPool(100)
pool.imap(fetch, urls)

如果您想了解更多相关信息,请查看greenpool.py中的代码。


所有绿色线程只运行一个线程。在所有绿色线程上尝试此操作,您将获得唯一的线程ID。

print greenthread.getcurrent(), threading.current_thread()

如果没有eventlet.sleep进行循环,则线程会一直被阻塞。其他绿色线程没有机会安排。因此,您的问题的一个可能解决方案是在while循环中调用spawn后调用eventlet.sleep。

答案 1 :(得分:0)

您可能希望使用Eventlet查看我的抓取工具:https://github.com/temoto/heroshi/blob/3b5e273783de9ea4b24cbcb0bf01a5025f653b93/heroshi/worker/Crawler.py

你收到袁的好评,我只想补充两件事:

    没有猴子修补的
  • time.sleep()会阻止整个过程,并且不会提取任何网址。请在开始时运行eventlet.monkey_patch()或使用eventlet.sleep()

  • 在流媒体网址上,您可能只想使用Heroshi master的io-worker。它是一个独立的程序,从stdin读取URL,抓取它们并将结果写入stdout。如果您真的想使用Eventlet,请使用共享队列,它可以工作:


pool = eventlet.GreenPool(100)
urls = eventlet.queue.Queue()
results = eventlet.queue.Queue()

urls.put('http://seed-url-1')
urls.put('http://seed-url-2')
# ...


def fetch(url):
  # ...
  results.put(...)


def crawl():
  while True:  # this is not C/Java, you don't need parens
    url = urls.get()
    pool.spawn(fetch, url)


def parse():
  while True:
    result = results.get()
    # ...
    urls.put(new_url_from_page)


eventlet.spawn(crawl)
eventlet.spawn(parse)