aiohttp:如何高效地下载响应体之前检查HTTP标头?

问题描述 投票:2回答:1

我写使用ASYNCIO / aiohttp网络爬虫。我希望抓取工具只需要下载HTML内容,并跳过一切。我写了一个简单的函数来筛选基于扩展网址,但因为很多下载链接,不包括在其中的文件名/扩展,这是不可靠的。

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

是否有可能只是发送一个普通的GET请求,并设置成aiohttp“流”模式,仅下载标题,然后用只有在MIME类型是正确的身体继续进行下载?或者是有用于滤除非HTML内容,我应该考虑的一些(快)的替代方法?


UPDATE

正如意见中的要求,我已经包括了我的意思通过使两个独立的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))
python http-headers web-crawler mime-types aiohttp
1个回答
0
投票

这是一个协议的问题,如果你做一个GET,服务器要发送的身体。如果不找回身体,你不得不丢弃的连接(其实这是它做什么,如果你不read()之前做__aexit__上的响应)。

所以上面的代码应该做更多的少,你想要什么。注:服务器可能在第一块已经有送不仅仅是头

© www.soinside.com 2019 - 2024. All rights reserved.