Это Общий ответ Я написал, потому что у меня была похожая проблема, ваша проблема может быть в том, что веб-сервер просит вас добавить эти куки в ваши дальнейшие запросы. Вы установили для своих файлов cookie значение ''
, поэтому они удаляются, а ваши новые файлы cookie добавляются в конец заголовков в соответствии с запросом серверов.
Что если мы просто используем get ():
import requests
import logging
import http.client as http_client
http_client.HTTPConnection.debuglevel = 1
#init logging
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
requests.get("http://google.com", allow_redirects=False)
Здесь я включил ведение журнала, чтобы вы могли видеть запросы по мере их выполнения (код регистрации не показан в следующих примерах). Это приводит к выводу:
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): google.com:80
send: b'GET / HTTP/1.1\r\nHost: google.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
...
Как видите, запросы инициируют некоторые заголовки, даже когда мы этого не сказали. Что произойдет, если мы передадим ему заголовки в нужном формате?
import requests
headers = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0"
}
requests.get("http://google.com", headers=headers, allow_redirects=False)
Здесь мы ожидаем, что «user-agent» будет отображаться в конце нашего запроса, однако выходные данные показывают иначе:
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): google.com:80
send: b'GET / HTTP/1.1\r\nHost: google.com\r\nuser-agent: Mozilla/5.0\r\naccept-encoding: gzip, deflate, br\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nConnection: keep-alive\r\naccept-language: en-US,en;q=0.9\r\nupgrade-insecure-requests: 1\r\n\r\n'
...
«User-agent» отображается в середине! Что дает? Давайте посмотрим на некоторый исходный код из библиотеки.
def __init__(self):
#: A case-insensitive dictionary of headers to be sent on each
#: :class:`Request <Request>` sent from this
#: :class:`Session <Session>`.
self.headers = default_headers()
...
Когда мы запускаем Session
, первое, что он делает, это назначает ему заголовки по умолчанию и любые дополнительные заголовки, предоставляемые Пользователь «косвенно» (через функцию) будет добавлен к стандартному.
Это проблема, так как при добавлении двух диктов (даже OrderedDicts) результат сохраняет порядок оригинальных диктов. Мы можем видеть это в приведенном выше примере, где атрибут «user-agent» сохранил свою позицию секунды в dict .
Это код для процесса добавления, если вам интересно:
def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
"""Determines appropriate setting for a given request, taking into account
the explicit setting on that request, and the setting in the session. If a
setting is a dictionary, they will be merged together using `dict_class`
"""
if session_setting is None:
return request_setting
if request_setting is None:
return session_setting
# Bypass if not a dictionary (e.g. verify)
if not (
isinstance(session_setting, Mapping) and
isinstance(request_setting, Mapping)
):
return request_setting
merged_setting = dict_class(to_key_val_list(session_setting))
merged_setting.update(to_key_val_list(request_setting))
# Remove keys that are set to None. Extract keys first to avoid altering
# the dictionary during iteration.
none_keys = [k for (k, v) in merged_setting.items() if v is None]
for key in none_keys:
del merged_setting[key]
return merged_setting
Так что же такое fix ?
Вам придется полностью переопределить заголовок по умолчанию. Я могу подумать, что для этого нужно использовать Session
, а затем напрямую заменить заголовок:
session = requests.Session()
headers = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"cookie": "Cookie: Something",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0"
}
# session.cookies.add_cookie_header(session)
session.headers = headers
a = session.get("https://google.com/", allow_redirects=False)
, которые дают желаемый результат, без необходимости каких-либо OrderedDict
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): google.com:443
send: b'GET / HTTP/1.1\r\nHost: google.com\r\naccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\naccept-encoding: gzip, deflate, br\r\naccept-language: en-US,en;q=0.9\r\ncookie: Cookie: Something\r\nupgrade-insecure-requests: 1\r\nuser-agent: Mozilla/5.0\r\n\r\n'
...
Приведенный выше пример доказывает, что все осталось там, где и должно быть, даже если вы проверите response.request.headers
все должно быть в порядке (по крайней мере, для меня это так)
PS: я не потрудился чтобы проверить, если использование OrderedDict имеет значение здесь, но если у вас все еще есть какие-либо проблемы, попробуйте использовать один вместо.