【爬虫实战】使用Python和JS逆向获取易车网汽车参数详情
前言
有的网站请求参数或者URL是明文的,但是有些是加密后的。接下来以易车网为例,巩固一下逆向思路。
一、目标分析
使用接口获取汽车的参数配置,但是请求参数无法直接阅读,点击解码即可。
请求头里还有一下加密参数
估计重点就是X-Sign,其他的可能用处不大。
其实可以试试直接请求接口,看是否有返回值:
1 | // https://mapi.yiche.com/web_api/car_model_api/api/v1/car/config_new_param?cid=508¶m=%7B%22cityId%22%3A%22201%22%2C%22carId%22%3A%22166210%22%7D |
所以重点来了,可能就是这个X-Sign起决定性因素。
二、逻辑分析
1. 定位函数获取X-Sign
只有两条记录,全部打上断点,进去哪个哪个就是。
看输出的值,有点像。
继续分析这句代码:
1 | "headers" == e.encryptType && (n["x-sign"] = u(e, t)); |
执行规则:
- 只要“&&”前面是false,无论“&&”后面是true还是false,结果都将返“&&”前面的值;
- 只要“&&”前面是true,无论“&&”后面是true还是false,结果都将返“&&”后面的值;
总结:假前真后
所以有效的的值一定是u(e, t)
。
接下来分别看一下e和t这两个参数:
1 | // t |
然后是e:
这不太对啊,接口地址不是这个,那就继续执行,当URL是config_new_param
再追踪。
果然有执行了几次才拿到了我们想要的结果。
也就是说如果开始找出了URL,那么后面的一切都是南辕北辙。
接下来就跳转到了s函数:
至此,我们找到了X-Sign的位置,之后使用JS来补环境就可以了吗?不要着急,执行一下没准能得到意想不到的结果。
好像恰巧获取的cid和param的值,而X-Sign就是加密后的密文。
2. 使用代码实现X-Sign
刚才我们获取了cid=508¶m={"cityId":"201","carId":"166210"}19DDD1FBDFF065D3A4DA777D2D7A81EC1700201316661
这个值,把这个值传给h函数,并把相同作用域的函数全部复制过来就可以了。很顺利,一次就跑通了。
接下来思考一下如何获取这个参数变量。我们回到刚才的s函数,可以看到这个参数是由n提供的。
可以看到就是把n参数进行一个MD5的处理,这时候我们可以猜测一下是不是普通的MD5,可以用python或者js代码试试:
1 | import hashlib |
可以看到和结果中是一致的。这就简单很多了,大部分逻辑就分析完了。
3. 编写Python代码,进行调用
根据前面的分析,可以确定以下参数是需要传值的:
- 查询参数
{"cityId":"201","carId":"166210"}
- 时间戳,可以从Python传过去,也可以直接使用JS来生成
其他值可以是固定或者处理过的。
三、代码实现
全部代码如下,使用python将字符串进行MD5处理,然后发出请求。需要注意以下几个问题:
- 有些字段是必须存在的,比如X开头几个,因为前面的JS代码中可以看到有使用到,否则就会报错;
- python的JSON数据和JS的JSON是有区别的,需要单独处理一下,否则校验失败。
以下代码是请求一种车型的方式,如果是批量请求,提前准备好多个ID就可以了。
1 | import json |
返回结果:
四、总结回顾
今天分析JS逻辑的时候在md5这一块卡了很久,主要原因如下;
- 起初看到进行MD5处理的时候怀疑了一下是不是基础的MD5,有没有进行特殊处理。为了图省事,直接问的GPT。结果这家伙输出了和控制台不一致的值,所以就当成JS特殊处理了。因此就把相关的函数单独拉出来进行处理,生成Sign值后传给python。但最后一直校验失败,百思不得其解。后来又多次反复查看使用Python生成MD5值后才发现了GPT的问题。但还是很奇怪为啥JS生成的MD5值不对呢,难到少复制什么函数或者变量了?
- 拼接参数的时候出现了Python和JS两个版本JSON不一致的问题,就是空格。
- 还发现个问题,在不同的浏览器上请求头存在大小写不一致的问题,但是并不影响结果。后来问了一下GPT,回答放在后面。
在HTTP协议中,请求头是不区分大小写的。这意味着,根据HTTP规范,请求头的字段名不应该被视为大小写敏感的。例如,
Content-Type
和content-type
在HTTP的角度来看是相同的。然而,实际上在某些情况下,服务器和浏览器的处理可能会导致大小写的差异。一些服务器可能会将请求头字段名视为大小写敏感,而另一些则可能不敏感。
此外,浏览器和其他HTTP客户端有时会以不同的方式处理请求头。有些浏览器可能会按照规范的方式处理,而另一些可能会将请求头字段名规范化为特定的形式。
为了确保在不同浏览器和服务器之间具有一致的行为,最好遵循HTTP规范,将请求头字段名视为不区分大小写。在编写代码时,最好使用规范的大小写形式。
因此,还是需要经验,多动手多动脑。