[英]Python 3 Requests or urllib - how to always add a header?
Title says it all: is there a 'best' way to always add a header to every request? 标题说明了一切:是否有一种“最佳”方式始终向每个请求添加标头? I've got an internal tool that wants to send request ids to other internal tools; 我有一个内部工具,希望将请求ID发送给其他内部工具。 I'm looking for a blessed solution. 我正在寻找一种有福的解决方案。 I've skimmed the docs of both and it seems that this isn't a popular thing to ask for as I can't find a cookbook example. 我已经浏览了两者的文档,并且由于我找不到菜谱示例,所以这似乎不是一件很受欢迎的事情。
I'm thinking of a couple solutions: 我在考虑几个解决方案:
import requests
but import myrequestswrapper as requests
. 需要教导合作开发者记住不要import requests
而是import myrequestswrapper as requests
。 edit: Why I'm not considering a requests.Session: it stores cookies and needs to be disposed of as it keeps its connection open. 编辑:为什么我不考虑request.Session:它存储cookie,并需要保持连接打开状态进行处理。
Create a session object , which is the 1st thing shown under advanced usage : 创建一个会话对象 ,这是高级用法下显示的第一件事:
s = requests.Session()
s.headers.update({'x-some-header': 'the value'})
s.get('http://httpbin.org/headers')
and use the session to perform requests. 并使用会话执行请求。 As you've stated that you do not wish to persist cookies between requests, you could subclass the Session
: 如前所述,您不想在请求之间保留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)]>
It is unfortunate that the Session
is by design difficult to extend and configure, so "disabling" cookies, and modifying pooling like this is a hack and prone to break, if and when Session
is updated the slightest. 不幸的是, Session
在设计上很难扩展和配置,因此“禁用” cookie并修改池这样的做法是很容易破解的,而且如果Session
进行最细微的更新也很容易中断。 Also we've disabled the 2 main features of Session
just for persistent headers. 另外,我们仅针对持久标头禁用了Session
的2个主要功能。
Wrapping the basic API methods is probably the cleaner and safer approach: 包装基本的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 action: 实际上:
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"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.