Python请求无法使用相同的密钥发送多个标头

时间:2013-05-28 10:33:14

标签: python python-requests

我正在尝试向具有两个具有相同名称但不同值的标头的服务器发送get请求:

url = 'whatever'
headers = {'X-Attribute':'A', 'X-Attribute':'B'}
requests.get(url, headers = headers)

这显然不起作用,因为标题字典不能包含两个键X-Attribute

我能做些什么,也就是说我可以将标题作为字典之外的其他内容传递?以这种方式发送请求的要求是服务器的一个特性,我无法改变它。

5 个答案:

答案 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)