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

文章目录

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

声明

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

目标分析

确定目标

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

目标检索

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

在这里插入图片描述

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

在这里插入图片描述

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

代码补全

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

在这里插入图片描述

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;

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

完整代码

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()

运行结果

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/373617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vite+Vue3项目配置启动项目后自动打开浏览器

有时候&#xff0c;我们在启动前端项目时&#xff0c;输入了启动命令&#xff0c;但却需要我们手动点开控制台输出的URL链接 如果每次都要点这个连接&#xff0c;会十分繁琐 为了提高开发效率&#xff0c;减少不必要的操作&#xff0c;我们就来解决这个问题。 1.在文件资源管…

Linux进程信号(3)--信号的处理

目录 前置知识 捕捉信号 内核如何实现信号的捕捉 sigaction 信号的其他补充问题 可重入函数 volatile关键字 SIGCHILD信号 前置知识 什么是用户态&#xff0c;内核态呢&#xff1f; 这里我们再来看看进程的地址空间&#xff1a; 我们知道每一个进程都会有自己的地址空…

大数据Zookeeper--案例

文章目录 服务器动态上下线监听案例需求需求分析具体实现测试 Zookeeper分布式锁案例原生Zookeeper实现分布式锁Curator框架实现分布式锁 Zookeeper面试重点选举机制生产集群安装多少zk合适zk常用命令 服务器动态上下线监听案例 需求 某分布式系统中&#xff0c;主节点可以有…

unity 增加系统时间显示、FPS帧率、ms延迟

代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;using UnityEngine;public class Frame : MonoBehaviour {// 记录帧数private int _frame;// 上一次计算帧率的时间private float _lastTime;// 平…

Docker 一小时从入门到实战 —— Docker commands | Create your own image | vs VM ... 基本概念扫盲

Docker crash course 文章目录 Docker crash course1. What and Why of Docker?2.1 What2.2 What problem does it solve?2.2.1 before containers2.1.2 with containers 2. Docker vs Virtual Machines2.1 Difference2.2 Benefits 3. Install docker locally4. Images vs Co…

微信小程序(三十四)搜索框-带历史记录

注释很详细&#xff0c;直接上代码 新增内容&#xff1a; 1.搜索框基本模板 2.历史记录基本模板 3.细节处理 源码&#xff1a; index.wxml <!-- 1.点击搜索按钮a.非空判断b.历史记录&#xff08;去重&#xff09;c.清空搜索框d.去除前后多余空格2.删除搜索 3.无搜索记录不…

springboot158基于springboot的医院资源管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

HTTP相关问题

目录 1.从输入URL到页面展示到底发生了什么&#xff1f; 2.HTTP状态码有哪些&#xff1f; 2.1 2XX(成功状态码) 2.2 3XX(重定向状态码) 2.3 4XX(客户端错误状态码) 2.4 5XX(服务端错误状态码) 3.HTTP 请求头中常见的字段有哪些&#xff1f; 4.HTTP和HTTPS有什么区别&…

[C++] 如何使用Visual Studio 2022 + QT6创建桌面应用

安装Visual Studio 2022和C环境 [Visual Studio] 基础教程 - Window10下如何安装VS 2022社区版_visual studio 2022 社区版-CSDN博客 安装QT6开源版 下载开源版本QT Try Qt | 开发应用程序和嵌入式系统 | Qt Open Source Development | Open Source License | Qt 下载完成&…

AI人工智能怎么自动抠图去除背景

抠图在许多场合中都发挥着重要的作用&#xff0c;它可以帮助我们去除图片的背景&#xff0c;从而将图片转换成透明底色&#xff0c;方便我们为图片更换其他的背景。为了实现照片去除背景只提取人物&#xff0c;我们需要使用专业的图片处理工具&#xff0c;并进行一系列的操作。…

算法效率的度量-时间空间复杂度

常对幂指阶 1.时间复杂度 事前预估 算法 时间开销 T(n) 与 问题规模 n 的关系&#xff08; T 表示 “ time ”&#xff09; 一般默认问题规模为n。 1.单循环 2.嵌套两层循环都为n 3.单层循环指数递增型 4.搜索型 链接 &#xff1a;第七章查找算法&#xff01;&#xff01…

elementUI 表格中如何合并动态数据的单元格

elementUI 表格中如何合并动态数据的单元格 ui中提供的案例是固定写法无法满足 实际开发需求 下面进行改造如下 准备数据如下 //在表格中 设置单元格的方法 :span-method"spanMethodFun" <el-table :data"tableData" border :span-method"spa…

2024第八届生物饲料高质量发展论坛会议通知

饲料工业发展空间大&#xff0c;产量持续增长&#xff0c;品质与质量也在不断提高&#xff0c;饲料工业是支撑现代畜牧水产养殖业发展的基础产业&#xff0c;是关系到城乡居民动物性食品供应的民生产业。“十四五”时期是我国由全面建设小康社会向基本实现社会主义现代化迈进的…

LeetCode、790. 多米诺和托米诺平铺【中等,二维DP,可转一维】

文章目录 前言LeetCode、790. 多米诺和托米诺平铺【中等&#xff0c;二维DP&#xff0c;可转一维】题目与分类思路二维解法二维转一维 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质…

性能测试工具LoadRunner与登录性能测试分析

1. LoadRunner与Jmeter Jmeter是开源免费的&#xff0c;LoadRunner是商业收费的。 但是LoadRunner具有非常强大的录制功能&#xff0c;具有丰富且灵活的场景&#xff0c;具备丰富的报告性能。 1&#xff09;Jmeter没有录制功能 2&#xff09;LoadRunner可以设计非常丰富的测试…

构造回文数组

目录 原题描述&#xff1a; 题目描述 时间&#xff1a;1s 空间&#xff1a;256M 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 样例1输入&#xff1a; 样例1输出&#xff1a; 样例2输入&#xff1a; 样例2输出&#xff1a; 约定&#xff1a; 作…

JVM 性能调优 - JVM 参数基础(2)

查看 JDK 版本 $ java -version java version "1.8.0_151" Java(TM) SE Runtime Environment (build 1.8.0_151-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) 查看 Java 帮助文档 $ java -help 用法: java [-options] class [args...] …

CSS:三列布局

三列布局是指左右两列定宽&#xff0c;中间自适应。最终效果如下&#xff1a; HTML&#xff1a; <div class"container"><div class"left"></div><div class"center"></div><div class"right">…

javaEE - 23( 21000 字 Servlet 入门 -1 )

一&#xff1a;Servlet 1.1 Servlet 是什么 Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app. 构建动态页面的技术有很多, 每种语言都有一些相关的库/框架来做这件事&#xff0c;Servlet 就是 Tomcat 这个 HTTP…

404. Sum of Left Leaves(左叶子之和)

问题描述 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 问题分析 我们可以查看如果一个叶子是左叶子就加上其值然后返回&#xff0c;如果是右叶子则不用关。 代码 int sumOfLeftLeaves(struct TreeNode* root) {int sum 0;if(root!NULL){if(root->left!…