分析请求
通过chrome的开发者工具抓网络请求得知,获取列表的接口为:https://tousu.sina.com.cn/api/index/s?ts=1699595319394&rs=fKQ4gGUG8AkGrby7&signature=c4e4b893b91c0e35fcce4ee0c9e5d1620e27c497e4f4e6103082d5ab5d35d272&keywords=大众汽车&page_size=10&page=1,其中有6个参数代表的含义如下所示:
- ts:时间戳
- rs:比较特殊,需要分析js获取
- keywords:搜索框中输入的关键字
- page_size:每页数据量
- page:页码
- signature:ts、rs、keywords、page_size、page所有请求参数和一个固定值$d6eb7ff91ee257475%组成的数组按照字母升序排序后组装成一个字符串,在使用sha256算法加密,得到最终的值。需要分析js得到加密算法
获取rs及固定值=$d6eb7ff91ee257475%
我这里直接截图吧,分析过程就是打断点,拦截请求,一步步找就行了,需要有耐心,具体位置见下图
获取signature
同样直接截图,其实已经找到位置了,一步步跟进去就能知道这个signature是怎么来得了
代码实现
通过分析参数,知道每个参数是怎么来的了,那我们直接用代码实现即可,本人主修java,你python能爬的,我java一样爬,废话不多说,直接上代码:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
public class Test {
public static void main(String[] args) throws Exception {
String js = IoUtil.readUtf8(ResourceUtils.getURL("classpath:js/rs.js").openStream());
String rs = Convert.toStr(ScriptUtil.invoke(js, "p"));
String url = "https://tousu.sina.com.cn/api/index/s?ts=%s&rs=%s&signature=%s&keywords=%s&page_size=%s&page=%s";
String keyWorld = "大众";
long ts = System.currentTimeMillis();
String b = "$d6eb7ff91ee257475%";
int pageSize = 10;
int page = 1;
String[] params = new String[] {Convert.toStr(ts), rs, b, keyWorld, Convert.toStr(pageSize), Convert.toStr(page)};
// 按字母升序排序
Arrays.sort(params);
String param = StrUtil.join("", params);
String signature = DigestUtil.sha256Hex(param);
String body = HttpUtil.createGet(String.format(url, ts, rs, signature, keyWorld, pageSize, page))
.timeout(50000)
.header(Header.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36")
.cookie("SUB=_2A25INP_5DeRhGeFG7DEU9C_EQnF4eTamfzaB9JwTL_PUNbm9AGLU3akW9NePjIHCcGaP4ABxr27x7fx9MkP5MLRKy9;") // 需要改下
.execute()
.body();
System.out.println(JSONUtil.toJsonStr(body));
}
}
rs.js放到resources下边的js目录下
function p(e, t, r) {
var n = ""
, i = t
, a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
e && (i = Math.round(Math.random() * (r - t)) + t);
for (var o = 0; o < i; o++) {
n += a[Math.round(Math.random() * (a.length - 1))]
}
return n
}(!1, 16);
实现思路是使用java代码执行js文件获取rs结果
其实看rs参数的js代码也不复杂,完全可以用java自己照着写一个(现在GPT这么牛逼,把js代码灌给GPT,让其帮我们用java代码实现,哈哈,有需要的朋友戳链接体验:Talk-Bot,不喜勿喷,广交益友),这里主要是想演示下如何用java去调用js代码,借用了hutool里边的工具类
备注
逆向之路修远兮,吾将上下而求索