Весь смысл использования asyncio заключается в том, что вы можете запускать несколько выборок одновременно (параллельно друг другу).Давайте посмотрим на ваш код:
for title in titles:
await fetch_again(session,title)
Эта часть означает, что каждый новый fetch_again
будет запускаться только после того, как ожидался предыдущий (законченный).Если вы делаете это таким образом, да, нет никакой разницы с использованием подхода синхронизации.
Чтобы задействовать всю мощь асинхронного запуска, запускайте несколько выборок одновременно, используя 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)
Важноnote
Хотя такой подход позволяет вам делать вещи намного быстрее, вы можете ограничить количество одновременных запросов одновременно, чтобы избежать значительного использования ресурсов как на вашей машине, так и на сервере.
Вы можете использовать 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