Простой запрос get / post заблокирован в Python 3, но не в Python 2

19

Я работаю над простым веб-шабером в Python 3, но когда я отправляю запрос get или post, ответом является 403. В Python 2 все работает нормально. Я использую одну и ту же версию библиотек запросов в обеих версиях. Я также пытался с, Verify=False/Trueно разница в обеих версиях остается.

запросы = 2.22.0

certifi = 2019.9.11

from requests import get
url = 'https://www.gamestop.com/'
header = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.5',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0',
    'DNT': '1',
    'Upgrade-Insecure-Requests': '1',
    'Connection': 'keep-alive',
    'Host': 'www.gamestop.com'
}
res = get(url, headers=header, verify=False).status_code
print(res)
# 403 when using python 3.7.4
# 200 when using python 2.7.16

Редактировать @blhsing:

Приведенный ниже список отслеживает, какие конкретные версии Python работают, а какие отказывают в соответствии с комментариями. До сих пор успехи и неудачи были согласованы для каждой конкретной версии Python на разных платформах.

Не стесняйтесь редактировать этот раздел вопроса со своими собственными результатами вместе с конкретными версиями Python, используемыми для получения результатов.

2.7.14 works (blhsing)
2.7.16 works (repl.it)
3.6.5 works (blhsing)
3.6.8 fails (Reinderien and blhsing)
3.7.3 works (wim and blhsing)
3.7.4 fails (repl.it and blhsing)
3.8.0 fails (OP)

Демонстрация на repl.it: Python 2.7.16 и Python 3.7.4

EDM
источник
Следует отметить, что это работает в Python 3.6, но не в 3.7.
blhsing
Я получаю «Доступ запрещен» даже в Firefox - после нескольких запусков кода в Python 3.7. Я не пробовал в Firefox до запуска Python - возможно, я заблокирован после использования кода Python или, возможно, он блокируется по другой причине - неправильный IP, неправильная страна, проблема на сервере.
фура
1
@ blhsing Да, это странно, я думаю, что тогда я пойду с 3.6, спасибо за примечание
EDM
2
Это странно. Используйте Wireshark и сравните запросы, отправленные Python 3.6 и 3.7. Должна быть какая-то разница, на которой работает сервер.
GordonAitchJay
1
Тогда это, вероятно, из-за различных openssl ( ssl.OPENSSL_VERSION). Вам не нужны все эти заголовки для воспроизведения, просто старый get (url) сделает это.
Вим

Ответы:

9

Это исключение, выданное urlib3:

/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: выполняется непроверенный HTTPS-запрос. Настоятельно рекомендуется добавить проверку сертификата. См .: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning,

В соответствии с последними примечаниями к выпуску, раздел 1.25.5 (2019-09-19) :

Добавьте смягчение для BPO-37428, затрагивающее Python <3.7.4 и OpenSSL 1.1.1+, что привело к включению проверки сертификата при использовании cert_reqs = CERT_NONE. (Выпуск № 1682 )

Вы можете следить за вопросом на Github , он был закрыт.

TLDR

Пользователь @sethmlarson на Github обнаружил эту ошибку на urllib3 :

create_urllib3_context ():

    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    # necessary for conditional client cert authentication with TLS 1.3.
    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    # versions of Python.
    if getattr(context, "post_handshake_auth", None) is not None:
        context.post_handshake_auth = True

установка этого значения Trueбудет включать проверку сертификатов сервера, вместо того, чтобы быть отключенной.

Наор Тедги
источник