Очистка контента с использованием pyppeteer в сочетании с asyncio - PullRequest
0 голосов
/ 13 декабря 2018

Я написал скрипт на 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://stackoverflow.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 Ответ

0 голосов
/ 14 декабря 2018

Проблема заключается в следующих строках:

tasks = [await browse_all_links(link, page) for link in linkstorage]
results = await asyncio.gather(*tasks)

Цель состоит в том, чтобы tasks был списком ожидаемых объектов, таких как объекты сопрограмм или фьючерсы.Список должен быть передан в gather, чтобы ожидаемые объекты могли работать параллельно, пока они не завершатся.Однако понимание списка содержит await , что означает, что оно:

  • выполняет каждый browser_all_links до завершения последовательно , а не параллельно;
  • помещает возвращаемые значения из browse_all_links вызовов в список.

Поскольку browse_all_links не возвращает значение, вы передаете списокNone возражает против asyncio.gather, который жалуется на то, что не получил ожидаемый объект.

Чтобы решить эту проблему, просто удалите await из списка.

...