写在前面

经过上一题的练习JS混淆---源码乱码,我们已经对JS混淆有了大致的了解,这次我们再来练习一道同类型的题目,只不过这次是动态Cookie


Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能, 而这一切都不必使用复杂的CGI等程序
举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存)
简单理解就是,Cookie相当于你浏览Web站点时,相对于这个站点的身份证号,如果说身份证号错误,肯定是不能正常访问这个站点的;这也是这次题目的考察内容

题目

题目部分截图
题目网址点我去刷题

提取全部5页发布日热度的值,计算所有值的加和,并提交答案

分析网页

由于是动态Cookie,为了避免其他Cookie的影响,所以使用浏览器的无痕模式进行调试,按f12并选中【Preserve log】

【Preserve log】:保留请求日志,跳转页面的时候勾选上,可以看到跳转前的请求(可以让我看到更详细的请求)

我们还是首先查看一下【XHR】里面的内容


可以很清楚的看到,页面当中的发布日热度值,就来源于这条链接 【http://match.yuanrenxue.com/api/match/2

我们尝试着在浏览器中打开这条链接,会得到这么一条信息

通过Unicode编码转换工具,翻译过来是:{"error": "出错啦~嘤嘤嘤"}
可以看得出,开发者还是挺会玩的,嘿嘿

出现这样的错误,也在意料之中,因为这道题目考的是动态Cookie,你去请求包含信息的链接时,Cookie不对,肯定是会报错的

我们继续查看XHR里面的内容,可以发现确实存在Cookie这么一个值的,而且这个加密的值跟上次的题目很像

那么这个Cookie是怎么生成的呢?

Cookie从何而来

我们回到调试工具,这次我们查看所有的请求信息,看看有没有其他的花样

可以发现,有两个名为【2】的请求
我们分别查看这两个请求,可以发现,第一个请求是不带Cookie的,第二个请求是带Cookie
不带Cookie
带Cookie

那么,我们就可以大胆的猜测,是不是第一个名为2的请求,执行了什么操作,让第二个名为2的请求带了Cookie

使用Fiddler.exe抓包

要想知道,第一个名为2的请求,到底发生了什么,我们可以使用Fiddler抓包软件,进行抓包查看
首先,我们打开这个软件(网上搜索就可以直接下载使用)
接着,打开无痕浏览器,进入到刷题网站,也就是这个链接【http://match.yuanrenxue.com/match/2
最后,我们回到Fiddler软件,会得到如下的信息

可以看到,熟悉的名为【2】的请求,也在当中

经过上面的猜测,我们知道,很有可能是第一个请求在暗地里做了些不为人知的操作
我们点击第一个【2】请求,点击response里面的Textview按钮,可以看到一段被混淆过的JS代码

看到这里的小伙伴可能就大概明白了,当发起第一个名为2的请求时,服务器端返回了一段JS代码,然后在浏览器里面执行了
现在我们只需要将这段混淆过的JS代码翻译一下,就能知道第一个请求到底做了些什么了

翻译混淆代码

我们将返回的JS代码复制下来,记得不要复制开头的<script>和结尾的</script>
然后,我们来到猿人学提供的翻译混淆代码的工具点我进入工具
我们将复制下来的代码,粘贴到第一个文本框,点击【一键解混淆】就行啦

接着,我们将翻译好的代码,复制到Notepad++里面,使用JS插件格式化一下

整段代码差不多200多行代码,而且这些函数名和变量名都非常奇怪,不过这些都不影响我们静下心来分析整段代码

分析JS代码

我们大致的浏览一下,全部代码,可以发现,大多数都是定义的函数,但是真正执行的只有最后的【 W(X());】

我们分析W()函数可以发现

function W(Y, Z) {
        document["cookie"] = "m" + M() + "=" + V(Y) + "|" + Y + "; path=/";
        location["reload"]();
    }

w()函数定义了两个形参,而执行的函数【 W(X());】,是传入一个参数的,而这个参数就是上面的X()函数

function X(Y, Z) {
        return Date["parse"](new Date());
    }

我们在谷歌调试工具里面执行X()函数就可以看到,返回的是一个时间戳,那么这个函数也会返回一个时间戳


X()函数我们弄清楚后,我们再来研究一下W()函数

分析W()函数

function W(Y, Z) {
        document["cookie"] = "m" + M() + "=" + V(Y) + "|" + Y + "; path=/";
        location["reload"]();
    }

看到【 document["cookie"] 】,我想大家已经明白了,Cookie是如何被设置的了
而后面的【 location["reload"](); 】,非常关键
这行代码的意思就是:刷新当前文档,也就是按了一下浏览器上的刷新页面按钮

现在我们重新理一下思路

  1. 网页向服务器发送请求,返回了两个名为【2】的结果
  2. 第一个没有Cookie,而第二个有Cookie
  3. 第一个虽然没有Cookie,但是却执行了一段JS代码
  4. 而这段JS代码给网页中的Cookie赋了值,接着刷新了整个页面
  5. 最后,呈现在我们眼前的网页,也就是第二个名为【2】的结果,有了Cookie

所以说,Cookie是怎么来的,我就不再赘述了,我们接着分析W()函数里面的代码

在分析代码之前,我们先对比一下,Cookie和这段代码

m=36674c3718305e203ee914bf011045c5|1609132022000
document["cookie"] = "m" + M() + "=" + V(Y) + "|" + Y + "; path=/";

最后面的【"; path=/"】字符串,是页面信息(第几页),在其他地方肯定是会处理的,这里我们可以省略
通过对比,赋值过程和赋值结果,我们可以发现赋值过程中的【 M() 】函数返回的一个应该是个空值
我们可以去分析一下M()函数

分析M()函数

话不多说,直接上代码

function M(Y, Z) {
        var a4 = B(this, function () {
            var a5 = function () {
                var a6 = a5["constructor"]("return /\" + this + \"/")()["compile"]("^([^ ]+( +[^ ]+)+)+[^ ]}");
                return !a6["test"](a4);
            };

            return a5();
        });
        a4();
        K();
        qz = [10, 99, 111, 110, 115, 111, 108, 101, 32, 61, 32, 110, 101, 119, 32, 79, 98, 106, 101, 99, 116, 40, 41, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 115, 41, 32, 123, 10, 32, 32, 32, 32, 119, 104, 105, 108, 101, 32, 40, 49, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 111, 114, 40, 105, 61, 48, 59, 105, 60, 49, 49, 48, 48, 48, 48, 48, 59, 105, 43, 43, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 105, 115, 116, 111, 114, 121, 46, 112, 117, 115, 104, 83, 116, 97, 116, 101, 40, 48, 44, 48, 44, 105, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 125, 10, 10, 125, 10, 99, 111, 110, 115, 111, 108, 101, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 91, 111, 98, 106, 101, 99, 116, 32, 79, 98, 106, 101, 99, 116, 93, 39, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 402, 32, 116, 111, 83, 116, 114, 105, 110, 103, 40, 41, 32, 123, 32, 91, 110, 97, 116, 105, 118, 101, 32, 99, 111, 100, 101, 93, 32, 125, 39, 10];
        eval(L(qz));

        try {
            if (global) {
                console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
            } else {
                while (1) {
                    console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
                    debugger;
                }
            }
        } catch (a5) {
            return navigator["vendorSub"];
        }
    }

首先,我们可以看到函数里面还包含着两个函数分别是【 a4() 】和【 K() 】
而这个【 a4() 】函数,也定义在M()内,但是执行【 a4() 】函数的时候,并没有传入参数,所以说,这段代码是没用的

接着,我们看一下K()函数

function K(Y, Z) {
        if (Z) {
            return J(Y);
        }

        return H(Y);
    }

需要传入参数,而执行的时候,又没有传入,所有这段代码也是是没用的
我们简化一下M()函数

function M(Y, Z) {
        qz = [10, 99, 111, 110, 115, 111, 108, 101, 32, 61, 32, 110, 101, 119, 32, 79, 98, 106, 101, 99, 116, 40, 41, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 115, 41, 32, 123, 10, 32, 32, 32, 32, 119, 104, 105, 108, 101, 32, 40, 49, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 111, 114, 40, 105, 61, 48, 59, 105, 60, 49, 49, 48, 48, 48, 48, 48, 59, 105, 43, 43, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 105, 115, 116, 111, 114, 121, 46, 112, 117, 115, 104, 83, 116, 97, 116, 101, 40, 48, 44, 48, 44, 105, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 125, 10, 10, 125, 10, 99, 111, 110, 115, 111, 108, 101, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 91, 111, 98, 106, 101, 99, 116, 32, 79, 98, 106, 101, 99, 116, 93, 39, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 402, 32, 116, 111, 83, 116, 114, 105, 110, 103, 40, 41, 32, 123, 32, 91, 110, 97, 116, 105, 118, 101, 32, 99, 111, 100, 101, 93, 32, 125, 39, 10];
        eval(L(qz));

        try {
            if (global) {
                console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
            } else {
                while (1) {
                    console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
                    debugger;
                }
            }
        } catch (a5) {
            return navigator["vendorSub"];
        }
    }

eval()函数又出现了,做过第一道题的时候,我们知道eval()可以间接的改变一些变量的值,那么这里的eval()是否对cookie有所改变呢?
我们来看看eval()中的L()函数

function L(Y, Z) {
        let a0 = "";

        for (let a1 = 0; a1 < Y["length"]; a1++) {
            a0 += String["fromCharCode"](Y[a1]);
        }

        return a0;
    }

L()函数可以传入两个参数,eval()执行的时候确实是传入一个参数的,这个参数是一个数组,正好用于L()函数中的for循环
for循环里面的内容就是将,传入的数组中的每一个值,通过【 String["fromCharCode"] 】这个方法翻译拼接着成一个字符串并返回
我也尝试着运行了这个函数,结果并没有什么卵用,就是一串字符串而已,感兴趣的同学可以去试试
这种就是典型的开发者挖坑,我们去踩

我们继续读下面的代码

        try {
            if (global) {
                console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
            } else {
                while (1) {
                    console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
                    debugger;
                }
            }
        } catch (a5) {
            return navigator["vendorSub"];
        }

try...catch 这个语法,我相信稍微学了点编程的同学,都知道是什么意思,我这里也不再阐述,不懂的同学可以问问百度
try里面的内容还是有点意思,直接进来就报错
我为什么这么说呢,是因为,global这个变量根本就没有定义,所有会直接报错,进入catch里面,虽然说传入了【a5】变量,但是在下面的代码并没有引用,可以不管
最后,直接return navigator["vendorSub"]

而这个navigator主要是包含有关浏览器的信息,它通过数组取值的方式取值,大概率返回的任然是空值.如果不是我们可以回来继续分析


那么,简化后的赋值代码可以这么写

cookie = "m" + "=" + V(Y) + "|" + Y;
          m=36674c3718305e203ee914bf011045c5|1609132022000
V(Y) = 36674c3718305e203ee914bf011045c5

所以说,我们现在就知道了,加密的值来源于【 V(Y) 】

在代码中分析【 V(Y) 】其实没必要,加密的过程过于复杂,我们直接使用鬼鬼JS调试工具,先验证一下我们猜想到达正不正确

验证猜想

我们将Notepad++里面的代码复杂粘贴到鬼鬼调试工具,记得删除第一行代码和最后一行代码
这是因为第一行是一个大函数,包含了很多小函数和变量,删除后,方面我们在工具中调试

在运行之前,我们先对代码进行如下的修改

  • 删除第一行代码和最后一行代码
  • 将代码中的let改为var,可以通过搜索let,进行修改
  • 删除104行左右的【 setInterval(M(), 500); 】这行代码,而这行代码的主要作用就是:每500毫秒,执行M(),而这个函数,我们在上面的推断是返回空所有没什么用,可以直接删掉
  • 在代码的开头定义 【 var navigator = {}; 】(这个navigator包含有关浏览器的信息,在运行代码的时候,由于执行了M()这个函数,而navigator没有定义(因为是在鬼鬼调试器中运行),会报错)
  • M()函数中,qz上面的多余代码直接删除,并没有什么卵用
  • W()函数中的内容,需要改写成下图的内容

接着,我们写一个get_cipher()函数用来返回【 W(X()) 】的值

可以看到,下面给出的执行结果是有值的,但是这还不严谨
我们还需要通过最后一个步骤进行验证
将Fiddler抓包工具,得到的m值后面的时间戳,复杂下来在调试工具中运行一下

m=36674c3718305e203ee914bf011045c5|1609132022000 (Fiddler抓包工具得到的值)


芜湖~起飞~,结果一模一样,我们可以愉快地写Python代码进行爬取数据啦!

最后的爬虫和解出答案

通过上面的一顿操作,我们可以编写一个JS文件,用于生成链接后面的密文
在Python代码中可以通过第三方库execjs,执行这个JS文件,得到密文

JS文件代码

var navigator = {};
var B = function () {
    var Y = true;
    return function (Z, a0) {
        var a1 = Y ?
        function () {
            if (a0) {
                var a2 = a0["apply"](Z, arguments);
                a0 = null;
                return a2;
            }
        }
         : function () {};
        Y = false;
        return a1;
    };
}
();

function C(Y, Z) {
    var a0 = (65535 & Y) + (65535 & Z);
    return (Y >> 16) + (Z >> 16) + (a0 >> 16) << 16 | 65535 & a0;
}

function D(Y, Z) {
    return Y << Z | Y >>> 32 - Z;
}

function E(Y, Z, a0, a1, a2, a3) {
    return C(D(C(C(Z, Y), C(a1, a3)), a2), a0);
}

function F(Y, Z, a0, a1, a2, a3, a4) {
    return E(Z & a0 | ~Z & a1, Y, Z, a2, a3, a4);
}

function G(Y, Z, a0, a1, a2, a3, a4) {
    return E(Z & a1 | a0 & ~a1, Y, Z, a2, a3, a4);
}

function H(Y, Z) {
    let a0 = [99, 111, 110, 115, 111, 108, 101];
    let a1 = "";

    for (let a2 = 0; a2 < a0["length"]; a2++) {
        a1 += String["fromCharCode"](a0[a2]);
    }

    return a1;
}

function I(Y, Z, a0, a1, a2, a3, a4) {
    return E(Z ^ a0 ^ a1, Y, Z, a2, a3, a4);
}

function J(Y, Z, a0, a1, a2, a3, a4) {
    return E(a0 ^ (Z | ~a1), Y, Z, a2, a3, a4);
}

function K(Y, Z) {
    if (Z) {
        return J(Y);
    }

    return H(Y);
}

function L(Y, Z) {
    let a0 = "";

    for (let a1 = 0; a1 < Y["length"]; a1++) {
        a0 += String["fromCharCode"](Y[a1]);
    }

    return a0;
}

function M(Y, Z) {
    qz = [10, 99, 111, 110, 115, 111, 108, 101, 32, 61, 32, 110, 101, 119, 32, 79, 98, 106, 101, 99, 116, 40, 41, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 32, 61, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 115, 41, 32, 123, 10, 32, 32, 32, 32, 119, 104, 105, 108, 101, 32, 40, 49, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 111, 114, 40, 105, 61, 48, 59, 105, 60, 49, 49, 48, 48, 48, 48, 48, 59, 105, 43, 43, 41, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 104, 105, 115, 116, 111, 114, 121, 46, 112, 117, 115, 104, 83, 116, 97, 116, 101, 40, 48, 44, 48, 44, 105, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 125, 10, 10, 125, 10, 99, 111, 110, 115, 111, 108, 101, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 91, 111, 98, 106, 101, 99, 116, 32, 79, 98, 106, 101, 99, 116, 93, 39, 10, 99, 111, 110, 115, 111, 108, 101, 46, 108, 111, 103, 46, 116, 111, 83, 116, 114, 105, 110, 103, 32, 61, 32, 39, 402, 32, 116, 111, 83, 116, 114, 105, 110, 103, 40, 41, 32, 123, 32, 91, 110, 97, 116, 105, 118, 101, 32, 99, 111, 100, 101, 93, 32, 125, 39, 10];
    eval(L(qz));

    try {
        if (global) {
            console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
        } else {
            while (1) {
                console["log"]("\u4EBA\u751F\u82E6\u77ED\uFF0C\u4F55\u5FC5python\uFF1F");
                debugger;
            }
        }
    } catch (a5) {
        return navigator["vendorSub"];
    }
}

function N(Y, Z) {
    Y[Z >> 5] |= 128 << Z % 32,
    Y[14 + (Z + 64 >>> 9 << 4)] = Z;

    if (qz) {
        var a0,
        a1,
        a2,
        a3,
        a4,
        a5 = 1732584193,
        a6 = -271733879,
        a7 = -1732584194,
        a8 = 271733878;
    } else {
        var a0,
        a1,
        a2,
        a3,
        a4,
        a5 = 0,
        a6 = -0,
        a7 = -0,
        a8 = 0;
    }

    for (a0 = 0; a0 < Y["length"]; a0 += 16)
        a1 = a5,
        a2 = a6,
        a3 = a7,
        a4 = a8,
        a5 = F(a5, a6, a7, a8, Y[a0], 7, -680876936),
        a8 = F(a8, a5, a6, a7, Y[a0 + 1], 12, -389564586),
        a7 = F(a7, a8, a5, a6, Y[a0 + 2], 17, 606105819),
        a6 = F(a6, a7, a8, a5, Y[a0 + 3], 22, -1044525330),
        a5 = F(a5, a6, a7, a8, Y[a0 + 4], 7, -176418897),
        a8 = F(a8, a5, a6, a7, Y[a0 + 5], 12, 1200080426),
        a7 = F(a7, a8, a5, a6, Y[a0 + 6], 17, -1473231341),
        a6 = F(a6, a7, a8, a5, Y[a0 + 7], 22, -45705983),
        a5 = F(a5, a6, a7, a8, Y[a0 + 8], 7, 1770010416),
        a8 = F(a8, a5, a6, a7, Y[a0 + 9], 12, -1958414417),
        a7 = F(a7, a8, a5, a6, Y[a0 + 10], 17, -42063),
        a6 = F(a6, a7, a8, a5, Y[a0 + 11], 22, -1990404162),
        a5 = F(a5, a6, a7, a8, Y[a0 + 12], 7, 1804603682),
        a8 = F(a8, a5, a6, a7, Y[a0 + 13], 12, -40341101),
        a7 = F(a7, a8, a5, a6, Y[a0 + 14], 17, -1502882290),
        a6 = F(a6, a7, a8, a5, Y[a0 + 15], 22, 1236535329),
        a5 = G(a5, a6, a7, a8, Y[a0 + 1], 5, -165796510),
        a8 = G(a8, a5, a6, a7, Y[a0 + 6], 9, -1069501632),
        a7 = G(a7, a8, a5, a6, Y[a0 + 11], 14, 643717713),
        a6 = G(a6, a7, a8, a5, Y[a0], 20, -373897302),
        a5 = G(a5, a6, a7, a8, Y[a0 + 5], 5, -701558691),
        a8 = G(a8, a5, a6, a7, Y[a0 + 10], 9, 38016083),
        a7 = G(a7, a8, a5, a6, Y[a0 + 15], 14, -660478335),
        a6 = G(a6, a7, a8, a5, Y[a0 + 4], 20, -405537848),
        a5 = G(a5, a6, a7, a8, Y[a0 + 9], 5, 568446438),
        a8 = G(a8, a5, a6, a7, Y[a0 + 14], 9, -1019803690),
        a7 = G(a7, a8, a5, a6, Y[a0 + 3], 14, -187363961),
        a6 = G(a6, a7, a8, a5, Y[a0 + 8], 20, 1163531501),
        a5 = G(a5, a6, a7, a8, Y[a0 + 13], 5, -1444681467),
        a8 = G(a8, a5, a6, a7, Y[a0 + 2], 9, -51403784),
        a7 = G(a7, a8, a5, a6, Y[a0 + 7], 14, 1735328473),
        a6 = G(a6, a7, a8, a5, Y[a0 + 12], 20, -1926607734),
        a5 = I(a5, a6, a7, a8, Y[a0 + 5], 4, -378558),
        a8 = I(a8, a5, a6, a7, Y[a0 + 8], 11, -2022574463),
        a7 = I(a7, a8, a5, a6, Y[a0 + 11], 16, 1839030562),
        a6 = I(a6, a7, a8, a5, Y[a0 + 14], 23, -35309556),
        a5 = I(a5, a6, a7, a8, Y[a0 + 1], 4, -1530992060),
        a8 = I(a8, a5, a6, a7, Y[a0 + 4], 11, 1272893353),
        a7 = I(a7, a8, a5, a6, Y[a0 + 7], 16, -155497632),
        a6 = I(a6, a7, a8, a5, Y[a0 + 10], 23, -1094730640),
        a5 = I(a5, a6, a7, a8, Y[a0 + 13], 4, 681279174),
        a8 = I(a8, a5, a6, a7, Y[a0], 11, -358537222),
        a7 = I(a7, a8, a5, a6, Y[a0 + 3], 16, -722521979),
        a6 = I(a6, a7, a8, a5, Y[a0 + 6], 23, 76029189),
        a5 = I(a5, a6, a7, a8, Y[a0 + 9], 4, -640364487),
        a8 = I(a8, a5, a6, a7, Y[a0 + 12], 11, -421815835),
        a7 = I(a7, a8, a5, a6, Y[a0 + 15], 16, 530742520),
        a6 = I(a6, a7, a8, a5, Y[a0 + 2], 23, -995338651),
        a5 = J(a5, a6, a7, a8, Y[a0], 6, -198630844),
        a8 = J(a8, a5, a6, a7, Y[a0 + 7], 10, 1126891415),
        a7 = J(a7, a8, a5, a6, Y[a0 + 14], 15, -1416354905),
        a6 = J(a6, a7, a8, a5, Y[a0 + 5], 21, -57434055),
        a5 = J(a5, a6, a7, a8, Y[a0 + 12], 6, 1700485571),
        a8 = J(a8, a5, a6, a7, Y[a0 + 3], 10, -1894986606),
        a7 = J(a7, a8, a5, a6, Y[a0 + 10], 15, -1051523),
        a6 = J(a6, a7, a8, a5, Y[a0 + 1], 21, -2054922799),
        a5 = J(a5, a6, a7, a8, Y[a0 + 8], 6, 1873313359),
        a8 = J(a8, a5, a6, a7, Y[a0 + 15], 10, -30611744),
        a7 = J(a7, a8, a5, a6, Y[a0 + 6], 15, -1560198380),
        a6 = J(a6, a7, a8, a5, Y[a0 + 13], 21, 1309151649),
        a5 = J(a5, a6, a7, a8, Y[a0 + 4], 6, -145523070),
        a8 = J(a8, a5, a6, a7, Y[a0 + 11], 10, -1120210379),
        a7 = J(a7, a8, a5, a6, Y[a0 + 2], 15, 718787259),
        a6 = J(a6, a7, a8, a5, Y[a0 + 9], 21, -343485441),
        a5 = C(a5, a1),
        a6 = C(a6, a2),
        a7 = C(a7, a3),
        a8 = C(a8, a4);

    return [a5, a6, a7, a8];
}

function O(Y) {
    var Z,
    a0 = "",
    a1 = 32 * Y["length"];

    for (Z = 0; Z < a1; Z += 8)
        a0 += String["fromCharCode"](Y[Z >> 5] >>> Z % 32 & 255);

    return a0;
}

function P(Y) {
    var a2,
    a3 = [];

    for (a3[(Y["length"] >> 2) - 1] = undefined, a2 = 0; a2 < a3["length"]; a2 += 1)
        a3[a2] = 0;

    var a1 = 8 * Y["length"];

    for (a2 = 0; a2 < a1; a2 += 8)
        a3[a2 >> 5] |= (255 & Y["charCodeAt"](a2 / 8)) << a2 % 32;

    return a3;
}

function Q(Y) {
    return O(N(P(Y), 8 * Y["length"]));
}

function R(Y) {
    var Z,
    a0,
    a1 = "0123456789abcdef",
    a2 = "";

    for (a0 = 0; a0 < Y["length"]; a0 += 1)
        Z = Y["charCodeAt"](a0),
        a2 += a1["charAt"](Z >>> 4 & 15) + a1["charAt"](15 & Z);

    return a2;
}

function S(Y) {
    return unescape(encodeURIComponent(Y));
}

function T(Y) {
    return Q(S(Y));
}

function U(Y) {
    return R(T(Y));
}

function V(Y, Z, a0) {
    M();
    return Z ? a0 ? H(Z, Y) : y(Z, Y) : a0 ? T(Y) : U(Y);
}

function W(Y, Z) {
    var cookie = "m" + "=" + V(Y) + "|" + Y;
    return cookie;
}

function X(Y, Z) {
    return Date["parse"](new Date());
}

function get_cipher() {
    return W(X());
}

话不到多,直接上爬虫代码,很简单,写了一些注释,我就不详细赘述了

# @BY     :Java_S
# @Time   :2020/12/26 12:14
# @Slogan :够坚定够努力大门自然会有人敲,别怕没人赏识就像三十岁的梵高

import requests
import execjs
import time

def get_cipher_value():
    # 导入JS,读取需要的js文件
    with open(r'JS/jsCookie.js',encoding='utf-8',mode='r') as f:
        JsData = f.read()
    # 加载js文件,使用call()函数执行,传入需要执行函数即可获取返回值
    psd = execjs.compile(JsData).call('get_cipher')
    return psd

def get_data(page_num,cipher):
    url = f'http://match.yuanrenxue.com/api/match/2?page={page_num}'
    headers = {
        'Host': 'match.yuanrenxue.com',
        'User-Agent':'yuanrenxue.project',
        'Cookie':cipher
    }
    print(f'加密密文--->{cipher}')
    response = requests.get(url,headers = headers)
    return response.json()


if __name__ == '__main__':

    sum_num = 0

    for page_num in range(1, 6):
        info = get_data(page_num, get_cipher_value())
        price_list = [i['value'] for i in info['data']]
        print(f'第{page_num}页发布日热度的值:{price_list}')
        sum_num += sum(price_list)
        time.sleep(1)

    print(f'发布日热度值总和:{sum_num}')

世界因代码而改变 Peace Out
最后修改:2021 年 01 月 18 日 08 : 03 PM
如果觉得我的文章对你有用,请随意赞赏