httpx, зависает рекурсивная задача asyncio

Я пытаюсь изучить asyncio с помощью python, я сделал асинхронный веб-скребок с httpx, aiohttp мне было сложно.

import aiofiles
import asyncio
import httpx
from lxml import html

async def fetchPage(url):

    try:
        
        response = await session.get(url)
        response.raise_for_status()
        return response

    except httpx.HTTPError as err:

        print(err)
        return None
 
async def downloadFile(filePage):

    filename = filePage.split("/")[-1]
    filePageResp = await fetchPage(filePage)
    filePageHtml = html.fromstring(filePageResp.content)
    fileURL = filePageHtml.xpath("//a[@class='download']")[0]

    async with session.stream("GET", url=fileURL) as fileResponse:
        async with aiofiles.open(filename, "wb") as file:
            async for chunk in contentResponse.aiter_bytes():
                if chunk:
                    await file.write(chunk)
            
async def main(URLs):

    for URL in URLs:

        resp = await fetchPage(URLs)
        htmlTree = html.fromstring(resp.content)
        filePages = htmlTree.xpath("//a[@class='filepage']/@href")
        tasks = [downloadFile(filePage) for filePage in filePages]
        taskResults = await asyncio.gather(*tasks)

    await session.aclose()    

if __name__ == "__main__":

    headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"}
    URLs = ("https://example.com/?page=1", "https://example.com/?page=2", "https://example.com/?page=3")
    # each page consists of about 20 links that lead to pages that have link for a file

    limits = httpx.Limits(max_connections=3)
    session = httpx.AsyncClient(headers=headers, limits=limits)
    asyncio.run(main(URLs))

Приведенный выше код работал нормально, пока я не начал получать 410 Gone во время загрузки файла. По-видимому, ссылки на файлы имеют строку запроса, которая устанавливает действительность, и это всего несколько минут, и к тому времени, а иногда и когда мой клиент пытается загрузить, ссылка уже истекла.

Итак, я ввел рекурсию:

async with session.stream("GET", url=fileURL) as fileResponse:
        if fileResponse.status_code == 410:
            return await downloadFile(filePage)

Теперь, когда возникает ошибка 410, мой сценарий просто зависает, что-то не так, и я не могу этого понять. Любая помощь приветствуется.

0 ответов

Другие вопросы по тегам