Python 从网络 headers 请求 403 Forbidden referer

Python requests 403 Forbidden referer from network headers

这个请求曾经有效,但现在得到了 403。我尝试像这个答案一样添加一个用户代理,但仍然没有用:

下面的第二个答案说找到引用者 header 但我无法弄清楚这些响应 header 在哪里:

import requests
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
"referer": "https://www.ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State"
job_url = "https://ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State"
job_response = requests.get(job_url,  headers=headers, timeout=10)
print(job_response)

这是我在刷新页面后第一个选项卡的请求 Headers 下看到的内容,但内容太多。我假设我只需要这些行之一。

:authority: www.ziprecruiter.com
:method: GET
:path: /Salaries/What-Is-the-Average-Programmer-Salary-by-State
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: max-age=0
cookie: __cfduid=dea4372c39465cfa2422e97f84dea45fb1620355067; zva=100000000%3Bvid%3AYJSn-w3tCu9yJwJx; ziprecruiter_browser=99.31.211.77_1620355067_495865399; SAFESAVE_TOKEN=1a7e5e90-60de-494d-9af5-6efdab7ade45; zglobalid=b96f3b99-1bed-4b7c-a36f-37f2d16c99f4.62fd155f2bee.6094a7fb; ziprecruiter_session=66052203cea2bf6afa7e45cae7d1b0fe; experian_campaign_visited=1
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36

编辑:查看其他选项卡,它们有 referer: "referer": "https://www.ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State" 所以我现在正在尝试,但它仍然是 403 .

使用 httpx package 它似乎适用于:

import httpx

url = 'https://ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State'

r = httpx.get(url)

print(r.text)
print(r.status_code)
print(r.http_version)

repl.it: https://replit.com/@bertrandmartel/ZipRecruiter

我可能错了,但我认为服务器不喜欢请求库的 TLS 协商。这很奇怪,因为上面的调用在请求中使用了 HTTP1.1,而 curl 它只适用于 http2 和 TLS1.3

使用通过 http2 和支持 TLS1.3 的 openssl 构建的 curl 二进制文件,以下工作:

docker run --rm curlimages/curl:7.76.1 \
    --http2 --tlsv1.3 'https://ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State' \
    -H 'user-agent: Mozilla' \
    -s -o /dev/null -w "%{http_code}"

returns:

301

以下命令失败:

  • 强制使用 http1.1 并强制使用 TLS 1.3
docker run --rm curlimages/curl:7.76.1 \
    --http1.1 --tlsv1.3 'https://ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State' \
    -H 'user-agent: Mozilla' \
    -s -o /dev/null -w "%{http_code}"

输出:403

  • 强制执行 http2 并强制执行 TLS 1.2:
docker run --rm curlimages/curl:7.76.1 \
    --http2 --tlsv1.2 'https://ziprecruiter.com/Salaries/What-Is-the-Average-Programmer-Salary-by-State' \
    -H 'user-agent: Mozilla' \
    -s -o /dev/null -w "%{http_code}"

输出:403

我的猜测是它在 TLS 协商中检测到一些东西,但是当同时存在 TLS1.3 和 HTTP/2

时检查是不同的

很遗憾,您无法使用 requests/urlib 检查 http/2,因为它不受支持