七麦数据爬虫案例

本文案例主要分析七麦数据榜单中的analysis参数。


url: https://www.qimai.cn/rank/index/brand/paid/device/iphone/country/cn/genre/5000

在这里插入图片描述

接口分析

经分析接口中有加密参数analysis。
在这里插入图片描述
cookie中参数由服务端返回,可以免cookie访问,所以只需要分析analysis。


逆向分析

全局搜analysis没有找到。 那么从堆栈进。
在这里插入图片描述
进来断点后,点一下别的榜单类型,触发请求。
在这里插入图片描述
可以发现触发断点的时候已经有 analysis了。
在这里插入图片描述
此时可以往回调试
在这里插入图片描述
多摁几下,摁了有5下看到了请求发起 添加参数的代码。
在这里插入图片描述
所以这里就是参数生成的地方。除了这种分析方式外,也可以通过注入hook Params代码 或者 AST漫游的方式来进行定位。

在该位置多下几个断点,刷新页面触发请求,F11往下调试。注意接口是否是 /rank/index。
在这里插入图片描述
往下继续调试, h + "=" + encodeURIComponent(a))
h = analysis
在这里插入图片描述

那怎么扣这个代码。 就是要把 a = (0,n.cv)((0,n.oZ)(r, l)) 和 后面的 -1 == e.url.indexOf(h)... 都搞出来

a = (0,n.cv)((0,n.oZ)(r, l))返回了一个字符串
后面的 -1 == e.url.indexOf(h)... 返回的是e,e中有analysis。

在这里插入图片描述

n.cv和n.oZ , e是请求对象,t是时间戳"1641980727.333"

function ncv(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)
    }
    )))
}

function noZ(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("")
}

r = "NTAwMGNuaXBob25lcGFpZA==@#/rank/index@#126855073625@#1"

l = "0000000c735d856"

在这里插入图片描述
所以在本地也执行一下 ,报错 ReferenceError: i is not defined 。
在这里插入图片描述
去在i那行断点,把i也拿下来。
在这里插入图片描述
再次运行程序,成功输出结果,并且和浏览器中的一样。
在这里插入图片描述
到这里并没有结束,可以发现r是一个随机值
在这里插入图片描述
把params的参数拿出来做一些处理。

接下来还是扣代码,这个过程就不说了,一点一点调试即可。

JS代码

最终扣下来的JS代码如下:

// 需要nodejs环境

function ncv(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)
    }
    )))
}

function noZ(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("")
}

function i(e) {
    var t, a = (t = "",
    ["66", "72", "6f", "6d", "43", "68", "61", "72", "43", "6f", "64", "65"].forEach((function(e) {
        t += unescape("%u00" + e)
    }
    )),
    t);
    return String[a](e)
}

// 此部分是f的生成,但是发现f是个定值,所以注释了
// var cookie = ""
// function nej(e) {
//     var t, a = new RegExp("(^| )" + e + "=([^;]*)(;|$)");
//     return (t = cookie.match(a)) ? unescape(t[2]) : null
// }
// var t = (0,nej)("synct");
// f = -(0,nej)("syncd") || +new Date - 1e3 * t

function get_analysis(xhr,brand){
    var f = 267;
    var l = "0000000c735d856";
    var a,
    o = +new Date - (f || 0) - 1515125653845,
    r = [];
    var e = {};
    e.url = xhr;
    e.params = {
        brand: brand,
        country: "cn",
        device: "iphone",
        genre: "5000"
    };
Object.keys(e.params).forEach((function(t) {
    if (t == false)
        return !1;
    e.params.hasOwnProperty(t) && r.push(e.params[t])
})),
    r = r.sort().join(""),
    r = (0,
    ncv)(r),
    r += "@#" + e.url.replace('https://api.qimai.cn', ""),
    r += "@#" + o,
    r += "@#" + 1,
    a = (0,ncv)((0, noZ)(r, l)),
    -1 == e.url.indexOf("analysis") && (e.url += (-1 != e.url.indexOf("?") ? "&" : "?") + "analysis" + "=" + encodeURIComponent(a)),
    e;
    return e
}

// console.log(get_analysis("/rank/index","paid"));

运行查看结果:
在这里插入图片描述


Python调用

【温馨提示:此处隐藏内容需要付费订阅后才能查看!】

运行
在这里插入图片描述

点赞
  1. 说道:
    Google Chrome Windows 10
    失效了吗?返回:{"code":10602,"msg":"Access Error","is_logout":0}

发表回复