python - aiohttp:如何在下载响应正文之前有效地检查 HTTP header ?

标签 python http-headers web-crawler mime-types aiohttp

我正在使用 asyncio/aiohttp 编写网络爬虫。我希望爬虫只想要下载 HTML 内容,而跳过其他所有内容。我编写了一个简单的函数来根据扩展名过滤 URL,但这并不可靠,因为许多下载链接中不包含文件名/扩展名。

我可以用 aiohttp.ClientSession.head()要发送 HEAD 请求,请检查 Content-Type字段以确保它是 HTML,然后发送单独的 GET 请求。但这会增加延迟,因为每页需要两个单独的请求(一个 HEAD,一个 GET),如果可能的话,我想避免这种情况。

是否可以仅发送常规 GET 请求,并将 aiohttp 设置为“流式”模式以仅下载 header ,然后仅在 MIME 类型正确时才继续下载正文?或者是否有一些(快速)替代方法可以过滤掉我应该考虑的非 HTML 内容?

更新

根据评论中的要求,我通过发出两个单独的 HTTP 请求(一个 HEAD 请求和一个 GET 请求)包含了一些我的意思的示例代码:

import asyncio
import aiohttp

urls = ['http://www.google.com', 'http://www.yahoo.com']
results = []

async def get_urls_async(urls):
    loop = asyncio.get_running_loop()

    async with aiohttp.ClientSession() as session:
        tasks = []

        for u in urls:
            print(f"This is the first (HEAD) request we send for {u}")
            tasks.append(loop.create_task(session.get(u)))

        results = []
        for t in asyncio.as_completed(tasks):
            response = await t
            url = response.url

            if "text/html" in response.headers["Content-Type"]:
                print("Sending the 2nd (GET) request to retrive body")
                r = await session.get(url)
                results.append((url, await r.read()))
            else:
                print(f"Not HTML, rejecting: {url}")

        return results

results = asyncio.run(get_urls_async(urls))

最佳答案

这是一个协议(protocol)问题,如果你做 GET ,服务器要发送正文。如果您不检索正文,则必须放弃连接(这实际上是如果您不在响应中的 read() 之前执行 __aexit__ 的操作)。

所以上面的代码应该做更多你想做的事。注意服务器可能会发送第一个块,而不仅仅是头

关于python - aiohttp:如何在下载响应正文之前有效地检查 HTTP header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54496954/

相关文章:

python - 构建期间在 Dockerfile 中激活和切换 Anaconda 环境

python - OpenCV cv2.VideoCapture() 停止读取 RTSP IP 摄像机

python - 使用 anaconda 在 Windows 上安装 tensorflow

java - 当内容配置正确设置时,文件名获取 undefined.zip

c# - 将 header cookie 字符串映射到 CookieCollection,反之亦然

python - 如何实时解决线程死锁?

php - 如何在 PHP 中解析响应头?

Java:检查 robots.txt 是否允许 URL

symfony - 如何安全地检查节点是否为空? (Symfony 2 爬虫)

php - 如何在php中使用简单的dom html获取最后一个li的 anchor 标记