【问题标题】:Python 3 Requests or urllib - how to always add a header?Python 3 请求或 urllib - 如何始终添加标头?
【发布时间】:2016-09-13 19:43:10
【问题描述】:

标题说明了一切:是否有一种“最好”的方式来始终为每个请求添加标头?我有一个内部工具想将请求 ID 发送到其他内部工具;我正在寻找一个有福的解决方案。我浏览了两者的文档,似乎这不是一个受欢迎的要求,因为我找不到食谱示例。

我正在考虑几个解决方案:

  1. 在我自己的瘦包装器中包装请求并使用它。需要教导合作开发者记住不是import requests,而是import myrequestswrapper as requests
  2. 猴子补丁请求。我不喜欢猴子补丁,但也许只有这一次......?我害怕需要向这个特定系统发送标头的时候。

编辑:为什么我不考虑请求。会话:它存储 cookie 并且需要被处理,因为它保持连接打开。

【问题讨论】:

    标签: python python-requests urllib


    【解决方案1】:

    创建一个session object,这是advanced usage下显示的第一件事:

    s = requests.Session()
    s.headers.update({'x-some-header': 'the value'})
    s.get('http://httpbin.org/headers')
    

    并使用会话来执行请求。正如您所说,您不希望在请求之间保留 cookie,您可以将Session 子类化:

    In [64]: from requests.adapters import HTTPAdapter
    
    In [65]: from requests.cookies import cookiejar_from_dict
    
    In [66]: class CookieMonsterSession(Session):
        ...:     
        ...:     def __init__(self, *args, **kwgs):
        ...:         super(CookieMonsterSession, self).__init__(*args, **kwgs)
        ...:         # Override default adapters with 0-pooling adapters
        ...:         self.mount('https://', HTTPAdapter(pool_connections=1,
        ...:                                            pool_maxsize=0))
        ...:         self.mount('http://', HTTPAdapter(pool_connections=1,
        ...:                                           pool_maxsize=0))
        ...:     @property
        ...:     def cookies(self):
        ...:         """ Freshly baked cookies, always!"""
        ...:         return cookiejar_from_dict({})
        ...:     @cookies.setter
        ...:     def cookies(self, newcookies):
        ...:         """ OM NOM NOM NOM..."""
        ...:         pass
        ...:     
    
    In [67]: s = CookieMonsterSession()
    
    In [69]: real_s = Session()
    
    In [70]: s.get('http://www.google.fi')
    Out[70]: <Response [200]>
    
    In [71]: s.cookies
    Out[71]: <RequestsCookieJar[]>
    
    In [72]: real_s.get('http://www.google.fi')
    Out[72]: <Response [200]>
    
    In [73]: real_s.cookies
    Out[73]: <RequestsCookieJar[Cookie(version=0, name='NID', value='86=14qy...Rurx', port=None, port_specified=False, domain='.google.fi', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=1489744358, discard=False, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>
    

    不幸的是,Session 在设计上难以扩展和配置,因此“禁用”cookie 和像这样修改池是一种黑客行为,并且很容易被破坏,如果 Session 更新最轻微。此外,我们还禁用了 Session 的 2 个主要功能,仅用于持久标头。

    包装基本的 API 方法可能是更清洁、更安全的方法:

    # customrequests.py
    from functools import wraps
    from requests import api as requests_api
    
    custom_headers = {}
    
    
    def _header_wrapper(f):
        @wraps(f)
        def wrapper(*args, **kwgs):
            headers = kwgs.pop('headers', None) or {}
            headers.update(custom_headers)
            return f(*args, headers=headers, **kwgs)
    
        return wrapper
    
    request = _header_wrapper(requests_api.request)
    get = _header_wrapper(requests_api.get)
    options = _header_wrapper(requests_api.options)
    head = _header_wrapper(requests_api.head)
    post = _header_wrapper(requests_api.post)
    put = _header_wrapper(requests_api.put)
    patch = _header_wrapper(requests_api.patch)
    delete = _header_wrapper(requests_api.delete)
    

    在行动:

    In [1]: import customrequests as requests
    
    In [2]: print(requests.get('http://httpbin.org/headers').text)
    {
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "python-requests/2.11.1"
      }
    }
    
    
    In [3]: requests.custom_headers['X-Test'] = "I'm always here"
    
    In [4]: print(requests.get('http://httpbin.org/headers').text)
    {
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "python-requests/2.11.1", 
        "X-Test": "I'm always here"
      }
    }
    

    【讨论】:

    • 考虑了一下,但是:它存储了我不想要的 cookie,并且还保持连接打开,这可能会在整个应用程序生命周期内出现问题。
    • 如果这些是个问题,我建议您采用您最初的包装想法。查看代码时,您的添加是否正在使用中会立即显而易见。
    猜你喜欢
    • 2018-04-12
    • 2011-10-14
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多