Я пишу сканер, используя asyncio / aiohttp.Я хочу, чтобы сканер хотел только загружать контент HTML и пропустить все остальное.Я написал простую функцию для фильтрации URL-адресов на основе расширений, но это ненадежно, поскольку многие ссылки для загрузки не включают в себя имя файла / расширение.
Я мог бы использовать aiohttp.ClientSession.head()
для отправки запроса HEAD, проверьтеполе Content-Type
, чтобы убедиться, что это HTML, а затем отправить отдельный запрос GET.Но это увеличит задержку, требуя два отдельных запроса на страницу (один HEAD, один GET), и я хотел бы избежать этого, если это возможно.
Можно ли просто отправить обычный запрос GET и установить aiohttp в «потоковый» режим для загрузки только заголовка, а затем продолжить загрузку тела, только если тип 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))