1

**** 大家好

我正在使用 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 根本没有运行

顺便说一句,pool.imap 确实有效

发生了什么?

我想要做的是:url 源源不断地来,即一个接一个。像这样

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

但它也不起作用。

提前致谢....

4

2 回答 2

1

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

您可以尝试在脚本末尾添加一些等待或睡眠。然后那些产生的绿色线程将执行你的函数。

pool.waitall()

或者

eventlet.sleep(10)

实际上,在“for body 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 。

于 2014-07-13T13:21:51.037 回答
0

你可能想看看我使用 Eventlet 的爬虫:https ://github.com/temoto/heroshi/blob/3b5e273783de9ea4b24cbcb0bf01a5025f653b93/heroshi/worker/Crawler.py

袁先生的回复很好,我只想补充两点:

  • time.sleep()没有猴子补丁将阻止整个过程,并且不会获取任何 URL。在开始时运行eventlet.monkey_patch()或使用eventlet.sleep().

  • 在流式 URL 上,您可能只想使用 Heroshi master 的 io-worker。它是一个独立的程序,从标准输入读取 URL,抓取它们并将结果写入标准输出。如果你真的想为它使用 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)
于 2014-07-14T07:26:44.343 回答