#python #requests #словари
Использую библиотеку requests для выполнения запросов по сети. Но возникла проблема.
Когда указываю заголовки, то они идут в рандомном порядке
>>> headers = {'Connection':'keep-alive',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding':'gzip,deflate,sdch',
'Accept-Language':'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
'Cache-Control':'max-age=0',
'Origin':'http://site.ru',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/29.0.1547.0 Safari/537.36'}
>>> headers
{'Origin': 'http://site.ru', 'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
'Accept-Encoding': 'gzip,deflate,sdch', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/29.0.1547.0 Safari/537.36', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0'}
Origin перескакивает в самое начало. Суть в том, что сервер восприимчив к подобным
переменам, и заголовки надо отправлять в строго определенном порядке. Вычитал что это
проблема возникает из за того что используется словарь. Однако как я понял, requests
принимает header только в таком виде.
Подскажите, как можно решить данную проблему?
PS возможности вмешиваться в работу сервера нет.
Ответы
Ответ 1
И Вы и Python и Header'ы в HTTP используют словарь {"ключей":"значений"}, не имеет
никакого смысла указывать Header'ы по другому. Меняйте серверную часть, которая нормально
сможет обращаться к заголовкам по их "ключу". Что это за серверная часть, у которой
важен порядок словаря? Словарь на то и словарь, чтобы обращаться к значению по его
ключу. И я вас уверяю, даже не пытайтесь сдерживать порядок словаря, это невозможно,
при передаче данных порядка не будет. Есть конечно разного рода сортировка для словарей,
но она не применима конкретно к Header'ам, так как Header'ы сами по себе сконструированы
по принципу словаря.
Ответ 2
Порядок http-заголовков не гарантирован (ни в спецификации, ни на практике). Заголовки
могут быть переставлены при транспортировке через интернет. Хотя для целей спецификации
(Internet Message Format) заголовки не следует переставлять в общем, а некоторые заголовки
не должны переставляться вообще. См. Сохраняет ли HTTPMessage порядок ключей?
возможности вмешиваться в работу сервера нет.
Чтобы упорядочить свои заголовки, достаточно их как collections.OrderedDict передать
(так как dict в Питоне не упорядочен). Если вы хотите также свой порядок для заголовков,
которые requests самостоятельно выставляет, то можно их переопределить на Session объекте.
См. Header Ordering:
#!/usr/bin/env python3
from collections import OrderedDict
import requests
session = requests.Session()
session.headers = OrderedDict([
('Connection', 'keep-alive'),
('Accept-Encoding', 'gzip,deflate'),
('Origin', 'example.com'),
('User-Agent', 'Mozilla/5.0 ...'),
])
# ...
custom_headers = OrderedDict([('One', '1'), ('Two', '2')])
req = requests.Request('GET', 'https://httpbin.org/get', headers=custom_headers)
prep = session.prepare_request(req)
print(*prep.headers.items(), sep='\n')
Вывод:
('Connection', 'keep-alive')
('Accept-Encoding', 'gzip,deflate')
('Origin', 'example.com')
('User-Agent', 'Mozilla/5.0 ...')
('One', '1')
('Two', '2')
Порядок заголовков сохранён.