【问题标题】:python prepared requests - removing unwanted headerpython准备的请求-删除不需要的标头
【发布时间】:2021-06-22 13:09:12
【问题描述】:

我在处理这个代码块时遇到了问题:

with requests.Session() as s:
    _hs = s.headers
    
    req = requests.Request('POST', url, data=json.dumps(data), headers=headers)
    prepared_req = req.prepare()
    if 'Content-Length' in prepared_req.headers:
        prepared_req.headers.pop('Content-Length')
    rsp = s.send(prepared_req, timeout=self._TIMEOUT)
    try:
        rsp.raise_for_status()
    except requests.HTTPError:
        self._logger.exception("error in retrieving response from %s -- response content: %s",
                                        url, rsp.content)
        raise
    return rsp.json()

Content-Length 已从 PreparedRequest 标头中正确删除,但在 send 期间出现问题:

Traceback (most recent call last):
  File "/opt/projects/MyProj/my-http-client/my_http_client/http_client.py", line 297, in _http_post
    rsp = s.send(prepared_req, timeout=self._TIMEOUT)
  File "/home/user/venvs/my-http-client-venv/lib/python3.8/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/home/user/venvs/my-http-client-venv/lib/python3.8/site-packages/requests/adapters.py", line 472, in send
    low_conn.send(i)
  File "/usr/lib/python3.8/http/client.py", line 975, in send
    self.sock.sendall(d)
TypeError: a bytes-like object is required, not 'str'

如果我用del 删除标题,也会发生同样的事情:

del prepared_req.headers['Content-Length']

有人知道怎么回事吗?没有headers.pop,一切正常。

【问题讨论】:

    标签: python python-requests http-headers urllib3


    【解决方案1】:

    根据对相关question 的回答,在 python3 中,所有字符串默认为 Unicode,但通过网络发送时需要转换为字节。

    我怀疑问题出在data=json.dumps 行上,因为转储数据会将其转换为字符串而不是字节:

    In [1]: data=json.dumps(dict(a='somestring'))                                                                                                                                 
    
    In [2]: data                                                                                                                                                                  
    Out[3]: '{"a": "somestring"}'
    
    In [4]: type(data)                                                                                                                                                            
    Out[5]: str
    
    

    解决方法是将字符串编码为字节:

    In [6]: data=json.dumps(dict(a='somestring')).encode('utf-8')                                                                                                                 
    
    In [7]: data                                                                                                                                                                  
    Out[8]: b'{"a": "somestring"}'
    
    In [9]: type(data)                                                                                                                                                            
    Out[10]: bytes
    

    【讨论】:

      【解决方案2】:

      试过了,现在我有了这个:

      Traceback (most recent call last):
        File "/home/user/venvs/my-app-venv/lib/python3.8/site-packages/requests/adapters.py", line 470, in send
          low_conn.send(hex(len(i))[2:].encode('utf-8'))
      TypeError: object of type 'int' has no len()
      

      奇怪,在官方请求文档中删除标头的方式似乎正是这样 https://docs.python-requests.org/en/master/user/advanced/#prepared-requests

      【讨论】:

      • 我认为您的意思是将此作为对我的答案的评论,因为它不是您原始问题的答案。仅凭该 sn-p 无法说出导致该错误的原因,但 TypeError: object of type 'int' has no len() 告诉您 len(i) 在 int 中失败,因为 i 在 int 中不是预期的可迭代。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多