小能豆

使用请求库通过python3脚本访问api时出现http403错误,但通过浏览器访问时没有出现问题

python

当我尝试访问没有文档且不受官方支持的 API 时遇到问题。

问题是,如果我将 API 链接放入各种浏览器中,它可以正常工作,但当我尝试通过 python 脚本访问它时,会收到 403 错误。当我放入 Chrome 浏览器时,它会发回 200 ok 响应。

我假设它不是身份验证或 Cookie/会话数据,因为它通过各种不同的浏览器工作,并且我已经尝试过删除 Cookie 和退出网站等。所有这些似乎都有效。

我还假设它不是 IP 阻止或速率限制,因为它是一个单一的请求,并且来自同一 IP,它似乎工作正常。

但我可能假设错误。

所以用户代理标头一定是我尝试更改用户代理但没有成功的问题。我尝试更改各种标头数据,使其与我的 Chrome 浏览器相同,但似乎没有任何效果。我一整天都在互联网和堆栈溢出中搜索,但找不到解决方案

我的Python脚本:

import requests, json


data = "data"

headers = {
    '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.7',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
    'Cookie': '__cflb=02DiuFQAkRrzD1P1mdkJhfdTc9AmTWwYjJGtpDcTftSd2; X-Mapping-Server=s7; cf_clearance=I2RZ8gC2GNXzVT0nf_bcKUQEtU5oGRrFq6Eq1OjR_Xs-1696873939-0-1-5622ec48.635f2445.c3629c20-0.2.1696873939',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
}


# API endpoint
endpoint = f"http://link-to-api/{data}/

# Send an HTTP GET request to the API endpoint
response = requests.get(api_endpoint_url, headers=headers) 

if response.status_code == 200:
    data = response.json() 


    print(f"Response code: {response.status_code}")
    print(data)
else:
    print(f"{response.status_code} Error: {response.reason}")

预期输出:打印来自 API 的数据

实际输出:403 错误:禁止

那么有谁知道为什么我会收到 403 错误以及如何解决它,以便我可以从 python 脚本访问此 API。如果出现问题,因为我需要对其进行身份验证或有任何共享。

编辑:也许这与 HTTP 和 HTTPS 有关?

编辑2:更改为更通用,在对API进行逆向工程和一些研究后我发现我的目标api使用tls ja3指纹识别,我通过使用curl_cffi python模块将我的ja3指纹欺骗到chrome浏览器来绕过它。


阅读 58

收藏
2023-11-10

共1个答案

小能豆

首先,403 错误通常表示服务器理解客户端的请求,但拒绝执行它。在你的情况下,这可能是由于服务器对请求的某些方面进行了检查,而你的 Python 脚本的请求没有通过这些检查。

你已经尝试了一些方法,但我建议你再尝试以下几种方法:

1. 添加 Referer 头

有些网站对请求的 Referer 进行检查,确保请求是从一个合法的来源发出的。尝试在请求头中添加 Referer 头,将其设置为你的 API 站点的地址。

headers['Referer'] = 'http://link-to-api/'

2. 使用 Session 对象

尝试使用 requests.Session 对象,它可以帮助你维护持久性会话,包括 cookies 和其他信息。这可能有助于模拟更接近浏览器的行为。

with requests.Session() as session:
    response = session.get(api_endpoint_url, headers=headers)

3. 使用不同的 User-Agent

尝试使用不同的 User-Agent,模拟其他浏览器或设备。

headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/98.0'

4. 检查是否需要添加额外的参数

有时,API 需要特定的参数,而浏览器可能会自动添加这些参数。通过查看浏览器的开发者工具(Network 标签页)来确定是否有其他参数需要被添加到你的请求中。

5. 使用 Fiddler 或类似工具进行抓包

使用抓包工具(如 Fiddler)来捕获浏览器和 Python 脚本的请求。比较两者之间的差异,特别是请求头和参数方面。

6. 检查是否有 JavaScript 渲染

有些网站使用 JavaScript 动态生成内容或执行其他操作。如果是这样,你可能需要使用 Selenium 或类似的工具来模拟浏览器环境。

7. 检查是否有 TLS 握手的问题

你提到可能与 HTTP 和 HTTPS 有关。确保你的 Python 脚本和浏览器都在使用相同的协议(HTTP 或 HTTPS)。同时,确保 TLS 握手成功。你可以尝试使用 verify=False 参数来禁用证书验证,但请注意这可能存在安全风险。

response = requests.get(api_endpoint_url, headers=headers, verify=False)

尝试上述方法,看看是否有助于解决问题。如果问题仍然存在,可能需要更详细的分析,例如查看服务器的日志以了解拒绝请求的原因。

2023-11-10