













有个需求是要监控几十个APP每天在各个应用市场中的评分或评论情况,对于苹果 App Store、华为等提供了网页端应用市场的厂商来说,采集比较方便,但其他一些只能在APP端查看且加固过的就很麻烦了。还好已经有现成的工具提供了这些:七麦是一个提供 iOS&Android 应用市场多维度数据的平台,想必其也是通过爬虫采集。
虽然可以注册账号后登陆逐个检索查看所需信息,但还是用自动化来避免重复机械操作。这里以App Store中的微信为例。

观察“检索近一个月评论详情时”的请求过程,发现有个每次请求都会变化的 analysis 加密参数,如下:
请求地址:https://api.qimai.cn/app/comment
请求参数:
analysis: dQ51TyxjAEd/YwBHdR12TylwWRZ9dF9HfXR5TyldfRB5YiBEfXR5V31adVJ5bA8CeDVbAH1kYQB+QgNPdQ5mXgN3SFpSXWJcYglxCQZ8Z1xwEx9RQEAfWwtaVQFaQiETAQEIAAQICVUGDlYEdkIB
appid: 414478124
country: cn
sword:
commentType: default
star: all
sdate: 2021-09-03 00:00:00
edate: 2021-10-02 23:59:59
sdate 和 edate :数据检索的起止时间
star:评论星级
commentType:评论种类
sword:可以搜索关键平台
country:上架地区
appid:每个APP对应的id
analysis:这就是本文要找的 analysis 加密参数了
一眼看到 analysis 的值,有点像经过 base64 编码的,因为多次请求发现它的长度一定会被4整除且有时出现等号,decode 后是些不能直接显示的字符,可能先有过处理。
按以往步骤,先直接搜索 analysis 但找不到有过定义的地方,那就看请求调用的堆栈,在https://static.qimai.cn/static/js/6089.0c2b807f5a6250372f2f.js这个 js 里开始,下断点后往上一步步查看调用,找到生成 analysis 的地方:
r().interceptors.request.use((function(e) {
try {
if (!p && null == f) {
var t = (0, n.ej)(u);
f = c.default.prototype.difftime = -(0, n.ej)(m) || +new Date - 1e3 * t
}
var a, o = +new Date - (f || 0) - 1515125653845,
r = [];
return void 0 === e.params && (e.params = {}),
Object.keys(e.params).forEach((function(t) {
if (t == h) return ! 1;
e.params.hasOwnProperty(t) && r.push(e.params[t])
})),
r = r.sort().join(""),
r = (0, n.cv)(r),
r += d + e.url.replace(e.baseURL, ""),
r += d + o,
r += d + 1,
a = (0, n.cv)((0, n.oZ)(r, l)),
-1 == e.url.indexOf(h) && (e.url += ( - 1 != e.url.indexOf("?") ? "&": "?") + h + "=" + encodeURIComponent(a)),
e
} catch(e) {}
}
//n.cv方法
function h(e) {
return function(e) {
try {
return btoa(e)
} catch(t) {
return Buffer.from(e).toString("base64")
}
} (encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function(e, t) {
return i("0x" + t)
})))
}
//n.oZ方法
function g(e, t) {
t || (t = s());
for (var a = (e = e.split("")).length, n = t.length, o = "charCodeAt", r = 0; r < a; r++) e[r] = i(e[r][o](0) ^ t[(r + 10) % n][o](0));
return e.join("")
}
//参数l赋值
var l = (0, n.nF)("qimai|Technology", 1)
//n.nF方法
function v(e, t, a) {
var n, o, r = void 0 === a ? 2166136261 : a;
for (n = 0, o = e.length; n < o; n++) r ^= e.charCodeAt(n),
r += (r << 1) + (r << 4) + (r << 7) + (r << 8) + (r << 24);
return t ? ("0000000" + (r >>> 0).toString(16)).substr( - 16) : r >>> 0
}
继续下断点,发现每次变化的参数只有几个:
syncd 的值,这里可以固定;o 来自当前时间戳和 f;r 将请求参数的数组拼接成字符串;n.cv 方法是 base64,接着继续拼接 d、o 等参数;n.cv 和 n.oZ 两个方法,n.cv 前面已经说了是 base64,n.oZ则是遍历参数后按位异或后再拼接。传入的参数 r 和 l,l 通过 n.nF 方法计算后为固定值 00000008d78d46a。a 即为analysis。
另外注意:请求需带 cookie,且官方对每个 IP 地址的请求数量有限制,短时间内请求过多则会出现 IP 被限制的提示。
Python代码放在GitHub。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。