파이썬 3에서 간단한 웹 스크레이퍼로 작업하고 있지만 get 또는 post 요청을 보내면 응답은 403입니다. 파이썬 2에서는 잘 작동합니다. 두 버전에서 동일한 버전의 요청 라이브러리를 사용하고 있습니다. 나는 또한 시도 Verify=False/True
했지만 두 버전의 차이점은 남아 있습니다.
요청 = 2.22.0
인증 = 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
답변
이것은 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) 에 따르면 :
Python <3.7.4 및 OpenSSL 1.1.1+에 영향을주는 BPO-37428 에 대한 완화 기능을 추가
하여 cert_reqs = CERT_NONE을 사용할 때 인증서 확인이 활성화되었습니다. (문제 # 1682 )
Github 의 문제를 따를 수 있으며 폐쇄되었습니다.
TLDR
Github에서의 사용자 @sethmlarson는 에이 버그 발견 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
사용하지 않고 서버 인증서를 확인할 수 있습니다.