我正在尝试向具有两个具有相同名称但不同值的标头的服务器发送get请求:
url = 'whatever'
headers = {'X-Attribute':'A', 'X-Attribute':'B'}
requests.get(url, headers = headers)
这显然不起作用,因为标题字典不能包含两个键X-Attribute
。
我能做些什么,也就是说我可以将标题作为字典之外的其他内容传递?以这种方式发送请求的要求是服务器的一个特性,我无法改变它。
答案 0 :(得分:6)
requests
将请求标头存储在dict
中,这意味着每个标头只能出现一次。因此,如果不对requests
库本身进行更改,则无法发送多个具有相同名称的标头。
但是,如果服务器是HTTP1.1 compliant,则必须能够接受相同的一个标头,并使用逗号分隔的单个值列表。
答案 1 :(得分:5)
请求使用urllib2.urlencode(或类似的东西)来编码标题。
这意味着可以将元组列表作为有效负载参数而不是字典发送,从而将字典列表从字典强加的唯一键约束中释放出来。 urlib2.urlencode文档中描述了发送元组列表。 http://docs.python.org/2/library/urllib.html#urllib.urlencode
以下代码将解决问题,而不会出现扁平化或肮脏的黑客攻击:
url = 'whatever'
headers = [('X-Attribute', 'A'),
('X-Attribute', 'B')]
requests.get(url, headers = headers)
答案 2 :(得分:2)
请求现在将所有标题(已发送和已接收)存储在字典中不区分大小写。不过,除此之外,打开一个python控制台并写下:
headers = {'X-Attribute':'A', 'X-Attribute':'B'}
你得到的是未定义的行为。 (它似乎可以重现,但它完全未定义。)那么你真正发送给那个实例中的请求的是:
{'X-Attribute': 'A'} # or {'X-Attribute': 'B'}, we can never be certain which it will be
你可以尝试(但不会起作用):
headers = [('X-Attribute', 'A'), ('X-Attribute', 'B')]
但至少这将是完全定义的行为(你总是发送B)。正如@mata建议的那样,如果您的服务器符合HTTP/1.1
,那么您可以这样做:
import collections
def flatten_headers(headers):
for (k, v) in list(headers.items()):
if isinstance(v, collections.Iterable):
headers[k] = ','.join(v)
headers = {'X-Attribute': ['A', 'B', ..., 'N']}
flatten_headers(headers)
requests.get(url, headers=headers)
我希望这对你有所帮助。
答案 3 :(得分:1)
5年后,您是否仍然遇到此问题,但我一直在努力解决同一问题。这是对我有用的东西:
url = 'whatever'
headers = {'X-Attribute': "A,B"}
requests.get(url, headers = headers)
答案 4 :(得分:0)
我对params有同样的问题:
以上都不适合我。
从头开始构建列表是有效的
params=[]
params.append([])
params.append([])
params[0].append('X-Attribute')
params[0].append(var1)
params[1].append('X-Attribute')
params[1].append(var2)
requests.get(url, params=params)