我正在尝试学习如何使用Python的asyncio模块并发运行任务。在以下代码中,我有一个模拟的“网络爬虫”作为示例。基本上,我想让在任何给定时间最多只有两个活动的fetch()请求,并且我希望在sleep()期间调用process()。
import asyncio
class Crawler():
urlq = ['http://www.google.com', 'http://www.yahoo.com',
'http://www.cnn.com', 'http://www.gamespot.com',
'http://www.facebook.com', 'http://www.evergreen.edu']
htmlq = []
MAX_ACTIVE_FETCHES = 2
active_fetches = 0
def __init__(self):
pass
async def fetch(self, url):
self.active_fetches += 1
print("Fetching URL: " + url);
await(asyncio.sleep(2))
self.active_fetches -= 1
self.htmlq.append(url)
async def crawl(self):
while self.active_fetches < self.MAX_ACTIVE_FETCHES:
if self.urlq:
url = self.urlq.pop()
task = asyncio.create_task(self.fetch(url))
await task
else:
print("URL queue empty")
break;
def process(self, page):
print("processed page: " + page)
# main loop
c = Crawler()
while(c.urlq):
asyncio.run(c.crawl())
while c.htmlq:
page = c.htmlq.pop()
c.process(page)
然而,上述代码是逐个下载URL(不是并发下载两个URL),并且在获取所有URL之后才进行任何“处理”。我该如何使fetch()任务并发运行,并在sleep()期间调用process()函数?
process
变成一个协程,以便与循环一起调度或由其他等待它的东西来执行。 - dirn