在排除了协议的问题后,有些情况下,我们的headers也是设置正确的,仍然没办法取得数据,这又是为何呢?
问题呈现:
例如,在获取某图片网站的数据的时候,直接采用requests请求,并没有获取到相应的数据。在这个例子中,我并没有往headers中添加更多的内容,其实之前尝试过,后来发现,实际上并不需要。
import requests
url = "https://p****y.com/zh/illustrations/search/%e8%87%aa%e7%84%b6/"
headers = {
'User-Agent':'Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
}
req = requests.get(url,headers=headers)
print(req.text)
print(req.status_code)
请求结果(状态码为403,而且返回的内容中没有我们需要的内容):
其次怀疑可能是协议的问题,改用httpx重新请求,其结果也是一致的(代码略,可以参考上篇内容)
那么,为什么headers正确,请求不到数据?我们改用postman请求试试。
是可以正常请求到数据的,而且并没有携带过多的参数。
问题成因,可能是TSL/JA3:
JA3指纹(JA3 fingerprint)是一种用于网络流量分析的技术,旨在识别和分类不同的TLS(Transport Layer Security)客户端。TLS是一种常用于加密互联网通信的协议,它提供了安全的数据传输和身份验证机制。
JA3指纹通过分析TLS握手阶段中客户端和服务器之间交换的握手消息来创建一个唯一的指纹。在TLS握手期间,客户端和服务器交换一系列的握手消息,包括支持的TLS版本、密码套件、压缩算法和TLS扩展等信息。JA3指纹将这些消息中的特定字段进行哈希处理,生成一个字符串来表示客户端的TLS配置。
由于不同的TLS客户端在握手消息中的字段值可能会有所不同,因此它们生成的JA3指纹也会有所不同。这使得JA3指纹可以用于识别和区分不同类型的TLS客户端,例如Web浏览器、移动应用程序、恶意软件等。
通过分析网络流量中的JA3指纹,安全分析人员和网络管理员可以检测和识别异常的TLS行为、恶意软件的活动或者潜在的网络攻击。然而,值得注意的是,JA3指纹并非绝对可靠,因为攻击者可以通过更改TLS。
正常浏览器与requests发起请求的TSL/JA3差异:
这个网站可以展示当前请求的TSL信息:https://tls.browserleaks.com/json
正常用浏览器访问:
用代码请求:
import requests
url = "https://tls.browserleaks.com/json"
headers = {
'User-Agent':'Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
}
req = requests.get(url,headers=headers)
print(req.text)
print(req.status_code)
可见结果存在明显差异,也就是说可以通过检查ja3直接拒绝某些访问,尤其是最后两项,使用代码请求直接是空的。
解决:修改TSL/JA3指纹
使用requests库去完成这个事情是有些费劲的,但是已经有可以做到这个事情的工具:curl_cffi
使用之前先安装:
pip install curl_cffi
看一看指纹:
from curl_cffi import requests
url = "https://tls.browserleaks.com/json"
headers = {
'User-Agent':'Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
}
req = requests.get(url,headers=headers,impersonate='chrome')
print(req.text)
print(req.status_code)
请求结果:
使用curl_cffi尝试请求我们的数据:
from curl_cffi import requests
url = "https://p****y.com/zh/illustrations/search/%e8%87%aa%e7%84%b6/"
headers = {
'User-Agent':'Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
}
req = requests.get(url,headers=headers,impersonate='chrome')
print(req.text)
print(req.status_code)
已经可以正常请求到数据,并且响应代码为200。
如果遇到更为严谨的TSL/JA3检查,那还需要更为严谨的修改方式,使得通过代码的访问行为与浏览器访问的行为一致。