简单的 get/post 请求在 python 3 中被阻止,但在 python 2 中没有

Posted

技术标签:

【中文标题】简单的 get/post 请求在 python 3 中被阻止,但在 python 2 中没有【英文标题】:Simple get/post request blocked in python 3 but not in python 2 【发布时间】:2020-02-04 07:14:45 【问题描述】:

我正在 python 3 中开发一个简单的网络爬虫,但是当我发送 get 或 post 请求时,响应是 403。但在 python 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 编辑:

下面的列表会根据 cmets 跟踪哪些特定 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

【问题讨论】:

需要注意的是,这在 Python 3.6 中有效,但在 3.7 中无效。 即使在 Firefox 中,我也会得到“拒绝访问”——在 Python 3.7 中运行了几次代码之后。在运行 Python 之前我没有在 Firefox 中尝试过 - 可能我在使用 Python 代码后被阻止了,或者它可能因为其他原因而被阻止 - 错误的 IP、错误的国家、服务器上的问题。 @blhsing 是的,这很奇怪,我想我会选择 3.6,谢谢提醒 这很奇怪。使用 Wireshark 并比较 Python 3.6 和 3.7 发送的请求。服务器正在接受一些差异。 那么可能是由于openssl不同(ssl.OPENSSL_VERSION)。您不需要所有这些标头来复制,只需一个普通的旧 get(url) 即可。 【参考方案1】:

这是 urllib3 抛出的异常:

/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 不安全请求警告,

根据latest release notes, section 1.25.5 (2019-09-19):

为 BPO-37428 添加缓解措施影响 Python 1.1.1+ 导致在使用 cert_reqs=CERT_NONE 时启用证书验证。 (问题 #1682

你可以关注issue on Github,已经关闭了。

TLDR

User @sethmlarson on 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 将启用服务器证书验证,而不是被禁用。

【讨论】:

以上是关于简单的 get/post 请求在 python 3 中被阻止,但在 python 2 中没有的主要内容,如果未能解决你的问题,请参考以下文章

前段框架——Vue的get和post请求数据

vue中使用mockjs简单返回数据、包括get,post请求

get与post请求简单理解

Python使用requests发送请求

使用python封装get+post请求

python 发送 get post请求