当我尝试访问没有文档且不受官方支持的 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浏览器来绕过它。
首先,403 错误通常表示服务器理解客户端的请求,但拒绝执行它。在你的情况下,这可能是由于服务器对请求的某些方面进行了检查,而你的 Python 脚本的请求没有通过这些检查。
你已经尝试了一些方法,但我建议你再尝试以下几种方法:
有些网站对请求的 Referer 进行检查,确保请求是从一个合法的来源发出的。尝试在请求头中添加 Referer 头,将其设置为你的 API 站点的地址。
headers['Referer'] = 'http://link-to-api/'
尝试使用 requests.Session 对象,它可以帮助你维护持久性会话,包括 cookies 和其他信息。这可能有助于模拟更接近浏览器的行为。
requests.Session
with requests.Session() as session: response = session.get(api_endpoint_url, headers=headers)
尝试使用不同的 User-Agent,模拟其他浏览器或设备。
headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/98.0'
有时,API 需要特定的参数,而浏览器可能会自动添加这些参数。通过查看浏览器的开发者工具(Network 标签页)来确定是否有其他参数需要被添加到你的请求中。
使用抓包工具(如 Fiddler)来捕获浏览器和 Python 脚本的请求。比较两者之间的差异,特别是请求头和参数方面。
有些网站使用 JavaScript 动态生成内容或执行其他操作。如果是这样,你可能需要使用 Selenium 或类似的工具来模拟浏览器环境。
你提到可能与 HTTP 和 HTTPS 有关。确保你的 Python 脚本和浏览器都在使用相同的协议(HTTP 或 HTTPS)。同时,确保 TLS 握手成功。你可以尝试使用 verify=False 参数来禁用证书验证,但请注意这可能存在安全风险。
verify=False
response = requests.get(api_endpoint_url, headers=headers, verify=False)
尝试上述方法,看看是否有助于解决问题。如果问题仍然存在,可能需要更详细的分析,例如查看服务器的日志以了解拒绝请求的原因。