Можете ли вы получить элементы из asyncio.Queue до того, как он будет полностью заполнен другой функцией? - PullRequest
0 голосов
/ 23 февраля 2020

При использовании библиотеки asyncio в python 3.8.1 я хочу очистить все URL-адреса со страницы root с помощью get_root_urls, а затем посетить эти очищенные URL-адреса, чтобы найти дополнительные URL-адреса. Сначала я помещаю URL-адреса, найденные на странице root, в очередь root_q, а затем я создаю столько рабочих, сколько URL-адресов в этой первой очереди, чтобы найти на веб-сайте больше URL-адресов с scrape_root_urls, которые затем помещаются в очередь моего конвейера pipe_q.

async def scrape_urls(root_url, pipe_q):
    root_q = asyncio.Queue()

    async with aiohttp.ClientSession() as session:
        await get_root_urls(session, root_url, root_q)

        scrapers = [asyncio.create_task(scrape_root_urls(session, root_q, pipe_q)) for _ in range(root_q.qsize())]

        await asyncio.gather(*scrapers)

После очистки URL-адреса я бы хотел отфильтровать его, чтобы не было дубликатов, а были только URL-адреса с одного хоста. Я хотел бы сделать эту фильтрацию, поскольку URL-адреса вводятся в pipe_q, в противном случае мне придется подождать, пока все мои рабочие не закончат, и затем выполнить фильтрацию. Однако я не знаю, как это сделать, и если это вообще возможно

async def filter_urls():
    pipe_q = asyncio.Queue()
    root_url = 'https://example.com/'

    await scrape_urls(root_url, pipe_q)

    filters = [asyncio.create_task(filter_url(pipe_q)) for _ in range(pipe_q.qsize()]

    await asyncio.gather(*filters)

Это моя текущая настройка, и, очевидно, она не работает так, как я хочу, так как она сначала заполняет весь pipe_q до того, как фильтрация URL-адресов в нем. Есть ли способ сделать доступ к очереди, пока поступают предметы? Или можно только подождать, пока он не закончится, а затем go снова через эту очередь?

...