“极简壁纸“爬虫JS逆向·实战

news/2024/7/19 8:39:56 标签: javascript, 爬虫, 服务器

文章目录

  • 声明
  • 目标分析
    • 确定目标
    • 目标检索
  • 代码补全
    • 完整代码
  • 爬虫逻辑
    • 完整代码
  • 运行结果

声明

本教程只用于交流学习,不可用于商业用途,不可对目标网站进行破坏性请求,请遵守相关法律法规。

目标分析

确定目标

  • 获取图片下载链接
    在这里插入图片描述

目标检索

  • 并不能搜索到链接明文数据,说明数据是动态渲染的。
    在这里插入图片描述
  • 查看发包,有一个getData很可疑,返回加密数据
    在这里插入图片描述
  • 添加XHR断点,切换页面触发函数

在这里插入图片描述

  • 一步步走,找到密文数据
    在这里插入图片描述
  • 继续跟,找到明文数据,说明解密函数就在其中

在这里插入图片描述

  • 进一步分析,可以找到解密处,json parse之后就从密文变成了明文,可见,这就是解密函数
    在这里插入图片描述

代码补全

  • 复制加密片段,控制台打印,发现_0x1683d3['a']['decipher']就是 _0x58b5da函数
javascript">out_data = JSON['parse'](_0x1683d3['a']['decipher'](_0x16dafc['data']['result']))

在这里插入图片描述

javascript">ori_code = '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'
out_data = JSON['parse'](_0x58b5da(ori_code))
console.log(out_data)
  • 下面就是缺什么补什么,直接搜索加进去就好了

有一点需要注意的是,出现 ReferenceError: window is not defined的情况 ,这是浏览器环境缺失,只要在开头添加一个 var window = global;

  • 成功拿到明文数据
    在这里插入图片描述

完整代码

javascript">var window = global;
function _0x3ef903(_0x44e9d9) {
    for (var _0x39da63, _0x53f955, _0x16f530 = '', _0x134aef = 0x0; _0x134aef < _0x44e9d9['length'];)
        _0x39da63 = _0x44e9d9[_0x134aef],
            _0x53f955 = 0x0,
            _0x39da63 >>> 0x7 === 0x0 ? (_0x16f530 += String['fromCharCode'](_0x44e9d9[_0x134aef]),
                _0x134aef += 0x1) : 0xfc === (0xfc & _0x39da63) ? (_0x53f955 = (0x3 & _0x44e9d9[_0x134aef]) << 0x1e,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x1]) << 0x18,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x2]) << 0x12,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x3]) << 0xc,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x4]) << 0x6,
                _0x53f955 |= 0x3f & _0x44e9d9[_0x134aef + 0x5],
                _0x16f530 += String['fromCharCode'](_0x53f955),
                _0x134aef += 0x6) : 0xf8 === (0xf8 & _0x39da63) ? (_0x53f955 = (0x7 & _0x44e9d9[_0x134aef]) << 0x18,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x1]) << 0x12,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x2]) << 0xc,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x3]) << 0x6,
                _0x53f955 |= 0x3f & _0x44e9d9[_0x134aef + 0x4],
                _0x16f530 += String['fromCharCode'](_0x53f955),
                _0x134aef += 0x5) : 0xf0 === (0xf0 & _0x39da63) ? (_0x53f955 = (0xf & _0x44e9d9[_0x134aef]) << 0x12,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x1]) << 0xc,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x2]) << 0x6,
                _0x53f955 |= 0x3f & _0x44e9d9[_0x134aef + 0x3],
                _0x16f530 += String['fromCharCode'](_0x53f955),
                _0x134aef += 0x4) : 0xe0 === (0xe0 & _0x39da63) ? (_0x53f955 = (0x1f & _0x44e9d9[_0x134aef]) << 0xc,
                _0x53f955 |= (0x3f & _0x44e9d9[_0x134aef + 0x1]) << 0x6,
                _0x53f955 |= 0x3f & _0x44e9d9[_0x134aef + 0x2],
                _0x16f530 += String['fromCharCode'](_0x53f955),
                _0x134aef += 0x3) : 0xc0 === (0xc0 & _0x39da63) ? (_0x53f955 = (0x3f & _0x44e9d9[_0x134aef]) << 0x6,
                _0x53f955 |= 0x3f & _0x44e9d9[_0x134aef + 0x1],
                _0x16f530 += String['fromCharCode'](_0x53f955),
                _0x134aef += 0x2) : (_0x16f530 += String['fromCharCode'](_0x44e9d9[_0x134aef]),
                _0x134aef += 0x1);
    return _0x16f530;
}

function _0x3ed467(_0x58f7d4) {
    for (var _0x4f1bcd = [-0x6f, 0x34, 0x5b, 0x41, -0x41, 0x74, 0x77, 0x6a, -0x79, -0x52, -0x5, 0x50, 0x33, 0x61, 0x44, -0x53, -0x70, -0x33, 0x17, -0x2e, -0x22, -0x72, -0x37, -0xb, -0x7f, 0x5a, 0x21, 0x16, -0x1f, 0x32, -0x11, 0x14, -0x2c, 0xf, -0x5e, -0x7b, 0x76, -0x17, -0x3d, 0x72, 0x47, -0x68, -0x7e, -0x75, -0x51, -0x36, -0x12, -0x6e, -0x4, -0x5f, -0x5b, 0x5e, -0x50, -0xe, 0x78, 0x69, 0x55, 0x68, -0x56, -0x6c, 0x43, 0x19, 0x65, 0x6c, 0x10, -0x69, 0x6f, -0xa, 0x75, -0x49, 0x4d, 0x59, -0x1d, -0x62, -0x44, 0x70, 0x6b, -0x1, 0x56, 0x79, 0x58, -0x65, -0x7c, 0x45, -0x1e, -0x8, -0x71, -0x4a, -0x76, 0x39, -0x19, 0xc, -0x73, -0x6a, 0x5f, 0x7f, 0x54, 0x7c, -0x66, -0x1c, 0x49, 0x2b, -0x3c, 0x1c, 0x2e, 0x73, 0x1e, 0x7a, -0x4b, 0x7d, -0x43, -0x4d, 0x3, -0x7, -0x35, -0xd, 0x35, 0x4e, -0x48, 0x1, 0xb, -0x47, -0x27, -0x4f, -0x3, 0x13, 0x29, 0x7e, -0x2b, -0x7d, -0x1b, 0x22, 0x3f, 0x8, 0x48, -0x23, -0x29, -0x3f, 0x3c, -0x18, 0x66, 0x2f, -0x77, -0x67, -0x16, 0x2d, 0x3b, 0x40, -0x60, 0x31, 0x53, -0x6b, -0x78, -0x39, -0x46, 0x0, -0x26, -0x54, -0x28, 0x18, 0xe, 0x30, 0x1d, 0x2c, -0x24, -0x2f, 0x38, -0x5c, 0x26, 0x25, 0x4, -0x32, 0x67, 0xa, -0x59, 0x37, 0x71, -0x1a, 0x6e, 0x36, 0x24, -0x14, -0x4e, -0xc, -0x74, 0x46, -0x25, 0x5, -0x3e, -0x4c, -0x30, -0x40, 0x4f, 0x64, 0x28, 0x6, -0x3a, -0x5a, -0x13, -0x9, 0x27, 0x5d, -0x63, 0x15, 0x7, 0x1a, -0x2, 0x1b, -0x2d, 0x51, 0x3a, -0x7a, 0x4c, -0x42, 0x2, 0x5c, -0x2a, 0x62, -0x10, 0x9, 0x3d, 0x3e, -0xf, 0x63, -0x15, 0x1f, -0x38, 0x57, 0x11, -0x34, -0x45, -0x21, -0x3b, -0x55, 0x42, 0x4a, 0x12, -0x5d, -0x80, -0x57, -0x20, 0x2a, 0x20, -0x58, 0x6d, 0x60, 0xd, -0x6, 0x4b, -0x64, -0x31, 0x23, -0x61, 0x52, -0x6d, 0x7b], _0x39eb66 = 0x0, _0x46445e = 0x0, _0x1360a5 = 0x0, _0x596013 = new Array(), _0x411913 = 0x0; _0x411913 < _0x58f7d4['length']; _0x411913++) {
        _0x39eb66 = _0x39eb66 + 0x1 & 0xff,
        _0x46445e = (0xff & _0x4f1bcd[_0x39eb66]) + _0x46445e & 0xff;
        var _0x5e20d4 = _0x4f1bcd[_0x39eb66];
        _0x4f1bcd[_0x39eb66] = _0x4f1bcd[_0x46445e],
        _0x4f1bcd[_0x46445e] = _0x5e20d4,
        _0x1360a5 = (0xff & _0x4f1bcd[_0x39eb66]) + (0xff & _0x4f1bcd[_0x46445e]) & 0xff,
        _0x596013['push'](_0x58f7d4[_0x411913] ^ _0x4f1bcd[_0x1360a5]);
    }
    return _0x596013;
}
function _0x4207c2(_0x2219f6) {
    for (var _0x9c7ad4 = window['atob'](_0x2219f6), _0x2dd788 = new Int8Array(_0x9c7ad4['length']), _0x7c7af6 = 0x0; _0x7c7af6 < _0x9c7ad4['length']; _0x7c7af6++)
        _0x2dd788[_0x7c7af6] = _0x9c7ad4['charCodeAt'](_0x7c7af6);
    return _0x2dd788;
}
function _0x563330(_0x1e29f9) {
    return _0x3ef903(_0x3ed467(_0x4207c2(_0x1e29f9)));
}

爬虫逻辑

下面就是编写爬虫 Python代码逻辑

  • 获取加密数据
  • 调用JS解密
  • 根据解密数据下载壁纸

完整代码

import os
import requests
import execjs
import json


def fetch_wallpaper_data(page=2, size=24):
    """从API获取壁纸数据。"""
    url = 'https://api.zzzmh.cn/bz/v3/getData'
    payload = {
        "size": size,
        "current": page,
        "sort": 0,
        "category": 0,
        "resolution": 0,
        "color": 0,
        "categoryId": 0,
        "ratio": 0
    }
    headers = {
        'Referer': 'https://bz.zzzmh.cn/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
    }
    response = requests.post(url=url, json=payload, headers=headers)
    return response.json()['result']


def compile_js():
    """编译JavaScript代码。"""
    with open('极简壁纸.js', encoding='utf-8') as file:
        js_code = file.read()
    return execjs.compile(js_code)


def decode_wallpaper_data(js_compiler, data):
    """使用编译的JavaScript代码解码壁纸数据。"""
    return json.loads(js_compiler.call('_0x563330', data))


def download_wallpaper(image_data, headers):
    """下载并保存壁纸。"""
    if not os.path.exists('img'):
        os.mkdir('img')

    for wallpaper in image_data['list']:
        num_suffix = '11' if wallpaper['t'] == 1 else '21'
        img_id = f"{wallpaper['i']}{num_suffix}"
        img_url = f'https://api.zzzmh.cn/bz/v3/getUrl/{img_id}'
        img_content = requests.get(url=img_url, headers=headers).content
        with open(f'img/{wallpaper["i"]}.jpg', mode='wb') as file:
            file.write(img_content)
        img_filename = f'img/{wallpaper["i"]}.jpg'
        print(f'已下载壁纸:{img_filename}')


def main():
    wallpaper_data = fetch_wallpaper_data()
    js_compiler = compile_js()
    decoded_data = decode_wallpaper_data(js_compiler, wallpaper_data)
    headers = {
        'Referer': 'https://bz.zzzmh.cn/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
    }
    download_wallpaper(decoded_data, headers)


if __name__ == '__main__':
    main()

运行结果

在这里插入图片描述

在这里插入图片描述


http://www.niftyadmin.cn/n/5368695.html

相关文章

【Git】06 常用场景

文章目录 前言一、场景11.1 删除分支1.2 修改message信息1.2.1 最新一次commit的message1.2.2 过去commit的message 1.3 合并commit1.3.1 多个连续commit合并1.3.2 不连续commit合并 二、场景22.1 比较暂存区和HEAD所含文件的差异2.2 比较工作区和暂存区所含文件的差异2.3 将暂…

excel 导出 The maximum length of cell contents (text) is 32767 characters

导出excel报错。错误日志提示&#xff1a;:The maximum length of cell contents (text) is 32767 characters 排查后&#xff0c;发现poi有单元格最大长度校验&#xff0c;超过32767会报错。 解决方案&#xff1a; 通过java反射机制&#xff0c;设置单元格最大校验限制为Int…

logback自定义生成DB日志(java环境)

目的&#xff1a; 未来在生成日志写入数据库中加一个特殊的字段&#xff0c;官方老版本提供的DBAppender无法实现&#xff0c;并且好巧不巧&#xff0c;在新版本这个实现也被删除了&#xff0c;所以重写一个实现。 1. 安装依赖 安装logback maven依赖 注意&#xff1a; lo…

安卓学习笔记之八:本地化的简单例子(kotlin版本)

本地化及多语言支持&#xff0c;是目前手机软件必须面对的问题&#xff0c;这里用一个简单的例子来说明在Android Studio下如何实现。 创建一个Empty Views Activity项目&#xff0c;语言选择Kotlin 实现一个简单的功能&#xff0c;一条欢迎&#xff0c;一个按钮&#xff0c;…

XUbuntu22.04之两款实用画笔工具(二百一十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

大语言模型微调数据集(2)

CLUE 数据集 CLUE 是一个中文语言理解测评基准,包括分类、命名实体识别和机器阅读理解任务。CLUE中的数据集为JSON格式。对于分类和命名实体识别数据集,我们将JSON格式转换为TSV格式,以便TencentPretrain可以直接加载它们;对于机器阅读理解数据集,我们保留原始格式,并将数…

Redis面试题42

人工智能对工作岗位和就业市场会有什么影响&#xff1f; 答&#xff1a;人工智能对工作岗位和就业市场将带来深远的影响。虽然一些工作可能会被自动化取代&#xff0c;但同时也将出现新的工作机会。以下是人工智能对工作岗位和就业市场的一些影响&#xff1a; 自动化工作&…

Linux 文件连接:符号链接与硬链接

Linux 文件连接&#xff1a;符号链接与硬链接 介绍 在 Linux 系统中&#xff0c;文件连接是一个强大的概念&#xff0c;它允许我们在文件系统中创建引用&#xff0c;从而使得文件和目录之间产生联系。在本文中&#xff0c;我们将深入探讨两种主要类型的文件连接&#xff1a;符…