Einfache Get / Post-Anfrage in Python 3 blockiert, aber nicht in Python 2

19

Ich arbeite an einem einfachen Web-Scraper in Python 3, aber wenn ich eine Get- oder Post-Anfrage sende, lautet die Antwort 403. In Python 2 funktioniert dies jedoch einwandfrei. Ich verwende in beiden Versionen dieselbe Version von Anforderungsbibliotheken. Ich habe es auch mit versucht, Verify=False/Trueaber der Unterschied in beiden Versionen bleibt bestehen.

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

Bearbeiten von @blhsing:

In der folgenden Liste wird nachverfolgt, welche bestimmten Python-Versionen funktionieren und welche Versionen gemäß den Kommentaren fehlschlagen. Bisher waren Erfolge und Misserfolge für jede spezifische Python-Version plattformübergreifend konsistent.

Sie können diesen Abschnitt der Frage mit Ihren eigenen Ergebnissen und den spezifischen Python-Versionen bearbeiten, mit denen die Ergebnisse erstellt wurden.

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)

Demo auf repl.it: Python 2.7.16 und Python 3.7.4

EDM
quelle
Es ist zu beachten, dass dies in Python 3.6 funktioniert, jedoch nicht in 3.7.
Blhsing
Ich bekomme sogar in Firefox "Zugriff verweigert" - nach wenigen Code-Ausführungen in Python 3.7. Ich habe es in Firefox nicht versucht, bevor ich Python ausgeführt habe - vielleicht bin ich blockiert, nachdem ich Python-Code verwendet habe, oder vielleicht blockiert es aus einem anderen Grund - falsche IP, falsches Land, Problem auf dem Server.
Furas
1
@blhsing yep das ist komisch, ich denke, ich werde dann mit 3.6 gehen, danke für Anmerkung
EDM
2
Das ist seltsam. Verwenden Sie Wireshark und vergleichen Sie die von Python 3.6 und 3.7 gesendeten Anforderungen. Es muss einen Unterschied geben, den der Server aufgreift.
GordonAitchJay
1
Dann liegt es wahrscheinlich an verschiedenen openssl ( ssl.OPENSSL_VERSION). Sie brauchen nicht alle diese Header, um zu reproduzieren, nur eine einfache alte get (url) wird es tun.
wim

Antworten:

9

Dies ist die von urlib3 ausgelöste Ausnahme:

/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Eine nicht überprüfte HTTPS-Anforderung wird gestellt. Das Hinzufügen einer Zertifikatsüberprüfung wird dringend empfohlen. Siehe: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning,

Gemäß den neuesten Versionshinweisen, Abschnitt 1.25.5 (2019-09-19) :

Fügen Sie eine Schadensbegrenzung für BPO-37428 hinzu, die Python <3.7.4 und OpenSSL 1.1.1+ betrifft, wodurch die Zertifikatsüberprüfung aktiviert wurde, wenn cert_reqs = CERT_NONE verwendet wird. (Ausgabe Nr. 1682 )

Sie können das Problem auf Github verfolgen , es wurde geschlossen.

TLDR

Benutzer @sethmlarson auf Github hat diesen Fehler auf urllib3 gefunden :

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

Wenn Sie diesen Wert auf setzen, Truewird die Überprüfung von Serverzertifikaten aktiviert, anstatt deaktiviert zu werden.

Naor Tedgi
quelle