首页 > 解决方案 > ProtocolError:接收到的标头值被 requests_async 中的空格包围

问题描述

为 RSS 提要编写异步抓取工具,有时某些站点会出现以下错误,例如:

In [1]: import requests_async as requests

In [2]: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Ch
   ...: rome/79.0.3945.79 Safari/537.36'}

In [3]: r = await requests.get('https://albumorientedpodcast.com/category/album-oriented/feed/', headers=headers)

这是此错误的完整回溯:

Traceback (most recent call last):
  File "rss_parser.py", line 55, in rss_downloader
    response = await requests.get(rss, headers=headers)
  File "C:\Python3\lib\site-packages\requests_async\api.py", line 11, in get
    return await request("get", url, params=params, **kwargs)
  File "C:\Python3\lib\site-packages\requests_async\api.py", line 6, in request
    return await session.request(method=method, url=url, **kwargs)
  File "C:\Python3\lib\site-packages\requests_async\sessions.py", line 79, in request
    resp = await self.send(prep, **send_kwargs)
  File "C:\Python3\lib\site-packages\requests_async\sessions.py", line 157, in send
    async for resp in self.resolve_redirects(r, request, **kwargs):
  File "C:\Python3\lib\site-packages\requests_async\sessions.py", line 290, in resolve_redirects
    resp = await self.send(
  File "C:\Python3\lib\site-packages\requests_async\sessions.py", line 136, in send
    r = await adapter.send(request, **kwargs)
  File "C:\Python3\lib\site-packages\requests_async\adapters.py", line 48, in send
    response = await self.pool.request(
  File "C:\Python3\lib\site-packages\http3\interfaces.py", line 49, in request
    return await self.send(request, verify=verify, cert=cert, timeout=timeout)
  File "C:\Python3\lib\site-packages\http3\dispatch\connection_pool.py", line 130, in send
    raise exc
  File "C:\Python3\lib\site-packages\http3\dispatch\connection_pool.py", line 120, in send
    response = await connection.send(
  File "C:\Python3\lib\site-packages\http3\dispatch\connection.py", line 56, in send
    response = await self.h2_connection.send(request, timeout=timeout)
  File "C:\Python3\lib\site-packages\http3\dispatch\http2.py", line 52, in send
    status_code, headers = await self.receive_response(stream_id, timeout)
  File "C:\Python3\lib\site-packages\http3\dispatch\http2.py", line 126, in receive_response
    event = await self.receive_event(stream_id, timeout)
  File "C:\Python3\lib\site-packages\http3\dispatch\http2.py", line 159, in receive_event
    events = self.h2_state.receive_data(data)
  File "C:\Python3\lib\site-packages\h2\connection.py", line 1463, in receive_data
    events.extend(self._receive_frame(frame))
  File "C:\Python3\lib\site-packages\h2\connection.py", line 1486, in _receive_frame
    frames, events = self._frame_dispatch_table[frame.__class__](frame)
  File "C:\Python3\lib\site-packages\h2\connection.py", line 1560, in _receive_headers_frame
    frames, stream_events = stream.receive_headers(
  File "C:\Python3\lib\site-packages\h2\stream.py", line 1055, in receive_headers
    events[0].headers = self._process_received_headers(
  File "C:\Python3\lib\site-packages\h2\stream.py", line 1298, in _process_received_headers
    return list(headers)
  File "C:\Python3\lib\site-packages\h2\utilities.py", line 335, in _reject_pseudo_header_fields
    for header in headers:
  File "C:\Python3\lib\site-packages\h2\utilities.py", line 291, in _reject_connection_header
    for header in headers:
  File "C:\Python3\lib\site-packages\h2\utilities.py", line 275, in _reject_te
    for header in headers:
  File "C:\Python3\lib\site-packages\h2\utilities.py", line 264, in _reject_surrounding_whitespace
    raise ProtocolError(
h2.exceptions.ProtocolError: Received header value surrounded by whitespace b'3.vie _dca '

同时,这个同一个站点通常是通过公共请求库加载的:

In [1]: import requests

In [2]: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Ch
   ...: rome/79.0.3945.79 Safari/537.36'}

In [3]: r = requests.get('https://albumorientedpodcast.com/category/album-oriented/feed/', headers=headers)

In [4]: r
Out[4]: <Response [200]>

我试图至少找到有关此错误的一些信息,但什么也没有。有人能告诉我我能做些什么来避免类似的错误并正常加载网站吗?

标签: python-3.xpython-requestspython-asyncio

解决方案


requests-async已存档,但其 github 页面包含指向后继者的链接 - httpx

httpx似乎有类似的语法并积极维护。

考虑尝试一下:那里可能已经修复了许多错误。


推荐阅读