入门级js逆向解析——猿人学爬虫攻防大赛题目12

wuchangjian2021-11-01 19:07:20编程学习

题目

猿人学Web端爬虫攻防刷题平台
在这里插入图片描述

直接注册即可,进入网站有指引说明,按步骤来就行

今天要做的是第十二题:

任务:抓取这5页的数字,计算加和并提交结果

在这里插入图片描述
在这里插入图片描述
题目详情可以进入查看,网站有反爬手段,selenium也不行

网页解析

F12 network查看请求,切换页码观察规律,主要变化为两个参数page和m
在这里插入图片描述
在这里插入图片描述
查看m的请求情况,initiator 中的request跳转到资源,在这里打个断点刷新下浏览器
查看到,m为btoa函数(base64位编码)加密结果

在这里插入图片描述
从js的btoa 、atob中抽取btoa函数部分,复制到浏览器的console中测试,如下图所示,并对照前面获得的m,对比两者确实一致

 var base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
   
   // btoa method
   function btoa (s) {
       if (/([^\u0000-\u00ff])/.test(s)) {
           throw new Error('INVALID_CHARACTER_ERR');
       }    
       var i = 0,
           prev,
           ascii,
           mod,
           result = [];


       while (i < s.length) {
           ascii = s.charCodeAt(i);
           mod = i % 3;


           switch(mod) {
               // 第一个6位只需要让8位二进制右移两位
               case 0:
                   result.push(base64hash.charAt(ascii >> 2));
                   break;
               //第二个6位 = 第一个8位的后两位 + 第二个8位的前4位
               case 1:
                   result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));
                   break;
               //第三个6位 = 第二个8位的后4位 + 第三个8位的前2位
               //第4个6位 = 第三个8位的后6位
               case 2:
                   result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));
                   result.push(base64hash.charAt(ascii & 0x3f));
                   break;
           }


           prev = ascii;
           i ++;
       }


       // 循环结束后看mod, 为0 证明需补3个6位,第一个为最后一个8位的最后两位后面补4个0。另外两个6位对应的是异常的“=”;
       // mod为1,证明还需补两个6位,一个是最后一个8位的后4位补两个0,另一个对应异常的“=”
       if(mod == 0) {
           result.push(base64hash.charAt((prev & 3) << 4));
           result.push('==');
       } else if (mod == 1) {
           result.push(base64hash.charAt((prev & 0x0f) << 2));
           result.push('=');
       }


       return result.join('');
   }

在这里插入图片描述

代码实例

import requests
import execjs  # pip install PyExecJS -安装引用包


def get_m(page):
    """使用复制过来的btoa函数 定义加密函数,获取m值"""

    with open("btoa.js", 'r', encoding='utf-8') as f:
        js = f.read()
    s = "yuanrenxue" + str(page)
    m = execjs.compile(js).call('btoa', s)
    return m


# # 测试
# print(get_m(1))

def get_json(page):
    url = "https://match.yuanrenxue.com/api/match/12?"
    params = {
        'page': page,
        'm': get_m(page)
    }
    # 点击第4 第5页 会跳出提示,填写自己的即可,注意cookie 不传请求到的数据是一样的,不是你页面上显示的数据
    # 记得打印对比下
    headers = {
        'user-agent': "yuanrenxue.project",
        'cookie': 'sessionid=使用你自己的seeionid'
    }

    response = requests.get(url, params=params, headers=headers)

    return response.json()


# # 数据请求测试
# print(get_json(1))

def sum_data():
    data = []
    """循环页码,取到所有数据,并计算求和"""
    for page in range(1, 6):
        json_data = get_json(page)
        print(json_data)
        for d in json_data.get("data"):
            data.append(d['value'])
    return sum(data)


if __name__ == '__main__':
    print("所有数字之和为:", sum_data())

请添加图片描述

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。