****嗨,全部
我正在使用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
但它也不起作用。
提前感谢....
答案 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)