1 回答
TA贡献1798条经验 获得超7个赞
使用 asyncio 的全部意义在于您可以同时运行多个提取(彼此并行)。让我们看看你的代码:
for title in titles:
await fetch_again(session,title)
这部分意味着fetch_again只有在等待(完成)之前才会开始每个新的。如果你这样做,是的,使用同步方法没有区别。
要调用 asyncio 的所有功能,请使用asyncio.gather以下命令同时启动多个提取:
await asyncio.gather(*[
fetch_again(session,title)
for title
in titles
])
你会看到显着的加速。
您可以进一步进行事件并fetch与fetch_again标题同时开始下一页:
async def processing_docs(session, html):
coros = []
tree = fromstring(html)
# titles:
titles = [
urljoin(link,title.attrib['href'])
for title
in tree.cssselect(".summary .question-hyperlink")
]
for title in titles:
coros.append(
fetch_again(session,title)
)
# next_page:
next_page = tree.cssselect("div.pager a[rel='next']")
if next_page:
page_link = urljoin(link,next_page[0].attrib['href'])
coros.append(
fetch(page_link)
)
# await:
await asyncio.gather(*coros)
重要的提示
虽然这种方法可以让您更快地做事,但您可能希望限制当时并发请求的数量,以避免在您的机器和服务器上大量使用资源。
您可以asyncio.Semaphore为此目的使用:
semaphore = asyncio.Semaphore(10)
async def fetch(url):
async with semaphore:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
text = await response.text()
result = await processing_docs(session, text)
return result
添加回答
举报