Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

Python requests: при указании заголовков запросы по сети идут в случайном порядке

#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') Порядок заголовков сохранён.

Комментариев нет:

Отправить комментарий