Очистка контента с использованием pyppeteer в сочетании с asyncio
Я написал скрипт на Python в сочетании с pyppeteer
вместе с asyncio
очистить ссылки на различные посты со своей целевой страницы и в конечном итоге получить заголовок каждого поста, отслеживая URL, ведущий к его внутренней странице. Контент, который я здесь проанализировал, не является динамическим. Тем не менее, я использовал pyppeteer
а также asyncio
чтобы увидеть, насколько эффективно это работает asynchronously
,
Следующий сценарий подходит для некоторых моментов, но затем выдает ошибку:
File "C:\Users\asyncio\tasks.py", line 526, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
Это то, что я написал до сих пор:
import asyncio
from pyppeteer import launch
link = "https://stackru.com/questions/tagged/web-scraping"
async def fetch(page,url):
await page.goto(url)
linkstorage = []
elements = await page.querySelectorAll('.summary .question-hyperlink')
for element in elements:
linkstorage.append(await page.evaluate('(element) => element.href', element))
tasks = [await browse_all_links(link, page) for link in linkstorage]
results = await asyncio.gather(*tasks)
return results
async def browse_all_links(link, page):
await page.goto(link)
title = await page.querySelectorEval('.question-hyperlink','(e => e.innerText)')
print(title)
async def main(url):
browser = await launch(headless=True,autoClose=False)
page = await browser.newPage()
await fetch(page,url)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(main(link))
loop.run_until_complete(future)
loop.close()
Мой вопрос: как я могу избавиться от этой ошибки и делать асинхронно?
1 ответ
Проблема в следующих строках:
tasks = [await browse_all_links(link, page) for link in linkstorage]
results = await asyncio.gather(*tasks)
Намерение для tasks
быть списком ожидаемых объектов, таких как объекты сопрограммы или фьючерсы. Список должен быть передан gather
, так что ожидаемые могут работать параллельно, пока они все не завершены. Однако, понимание списка содержит ожидание, что означает, что оно:
- выполняет каждый
browser_all_links
до завершения последовательно, а не параллельно; - помещает возвращаемые значения
browse_all_links
вызовы в список.
поскольку browse_all_links
не возвращает значение, вы передаете список None
возражает против asyncio.gather
, который жалуется, что не получил ожидаемый объект.
Чтобы решить проблему, просто бросьте await
из списка понимания.