Solicitação simples de get / post bloqueada no python 3, mas não no python 2

19

Estou trabalhando em um raspador da web simples no python 3, mas quando envio uma solicitação de recebimento ou postagem, a resposta é 403. No python 2 funciona bem. Estou usando a mesma versão das bibliotecas de solicitações nas duas versões. Eu também tentei com, Verify=False/Truemas a diferença em ambas as versões permanece.

pedidos = 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

Editar por @blhsing:

A lista abaixo controla quais versões específicas do Python funcionam e quais falham de acordo com os comentários. Até agora, sucessos e falhas foram consistentes para cada versão específica do Python entre plataformas.

Sinta-se à vontade para editar esta seção da pergunta com seus próprios resultados, juntamente com as versões específicas do Python usadas para produzir os resultados.

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)

Demonstração no repl.it: Python 2.7.16 e Python 3.7.4

EDM
fonte
Deve-se notar que isso funciona no Python 3.6, mas não no 3.7.
blhsing 6/10/19
Recebo "Acesso negado" mesmo no Firefox - depois de algumas execuções de código no Python 3.7. Não tentei no Firefox antes de executar o Python - talvez esteja bloqueado depois de usar o código Python ou talvez bloqueie por outro motivo - IP errado, país errado, problema no servidor.
furas
11
@blhsing sim isso é estranho, eu acho que eu vou com 3,6, em seguida, thx para a nota
EDM
2
Isso é estranho. Use o Wireshark e compare as solicitações enviadas pelo Python 3.6 e 3.7. Deve haver alguma diferença que o servidor está percebendo.
GordonAitchJay
11
Provavelmente é devido a diferentes openssl ( ssl.OPENSSL_VERSION). Você não precisa de todos esses cabeçalhos para reproduzir novamente, apenas um get (url) antigo simples o fará.
wim

Respostas:

9

Esta é a exceção lançada por urlib3:

/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: está sendo feita uma solicitação HTTPS não verificada. A adição de verificação de certificado é altamente recomendável. Consulte: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning,

De acordo com as notas de versão mais recentes, seção 1.25.5 (19/09/2019) :

Adicione atenuação para o BPO-37428 que afeta o Python <3.7.4 e o OpenSSL 1.1.1+, o que causou a ativação da verificação de certificado ao usar cert_reqs = CERT_NONE. (Edição 1682 )

Você pode acompanhar o problema no Github , que foi fechado.

TLDR

O usuário @sethmlarson no Github encontrou este bug no 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

definir esse valor como Truehabilitará a verificação de certificados do servidor, em vez de ser desativado.

Naor Tedgi
fonte