案例背景

假设我们需要爬取一家内部测试系统的动态数据API接口。该系统前端页面使用了复杂的JavaScript混淆技术来防止接口被直接调用,同时对请求参数进行了加密签名。另外,登录环节带有图形验证码用于防护。我们的目标是:

  • 分析JavaScript代码,逆向加密签名算法。
  • 模拟登录过程,自动识别图形验证码并提交。
  • 构造正确请求参数,获取动态数据。
  • 完整实现Python爬虫,稳定批量抓取数据。

环境准备

  • Python 3.8+
  • 主要依赖库:
    • requests (HTTP请求)
    • execjs (调用JavaScript引擎)
    • Pillow & pytesseract(验证码图像处理与OCR)
    • jsbeautifier(JS格式化辅助阅读)
    • lxml(HTML解析)
    • selenium & webdriver-manager(动态交互及验证码抓取,可选)

Step 1:分析网页结构和JavaScript代码

模拟环境下,打开前端页面,按F12打开开发者工具:

  • 页面HTML框架简单,核心数据通过POST提交参数调用 /api/v1/getData 接口,返回JSON。
  • POST请求中的参数均为加密后的签名串,且请求头带有特殊字段 X-Custom-Token
  • 登录页带有断码的图形验证码,图片URL是 /captcha/image,验证码刷新时参数带时间戳。

1.1 网络数据初探

使用Chrome Network面板,关注XHR请求:

POST https://internal.test/api/v1/getData
Request Payload:
{"param": "EncryptedStringHere","sign": "GeneratedSignature"
}
Response:
{"code": 0,"data": [ ... ]
}

1.2 找到加密签名函数

通过Sources面板,加载执行的JS文件(例如main.min.js,经过混淆压缩),使用jsbeautifier进行格式化,定位请求相关代码片段。

逆向发现关键函数generateSign(params)

function generateSign(params) {var a = btoa(encodeURIComponent(JSON.stringify(params)));var b = someObfuscatedFunction(a);return md5(b + secretKey);
}

大致逻辑是:

  • 将参数JSON字符串化,编码成URI,再做Base64编码。
  • 经过部分混淆函数处理(someObfuscatedFunction)。
  • 最后加上固定密钥用MD5加密。

Step 2:JavaScript逆向与关键代码还原

2.1 还原混淆函数

原始混淆函数结构类似:

function someObfuscatedFunction(str) {var res = '';for (var i = 0; i < str.length; i++) {res += String.fromCharCode(str.charCodeAt(i) ^ 123); // 按位异或123}return res;
}

这是典型的异或加密,解密时再次异或同样的数字即可还原。

2.2 Python实现等效签名函数

利用Python的base64hashlib和自定义异或函数实现:

import base64
import hashlib
import urllib.parsesecret_key = 'FixedSecretKey123'  # 从JS中提取的密钥def xor_str(s, key=123):return ''.join(chr(ord(c) ^ key) for c in s)def generate_sign(params):# JSON序列化import jsonparam_str = json.dumps(params, separators=(',', ':'), ensure_ascii=False)# URI编码encoded = urllib.parse.quote(param_str)# Base64编码b64 = base64.b64encode(encoded.encode('utf-8')).decode('utf-8')# 异或处理xor_result = xor_str(b64)# 计算MD5签名sign_str = xor_result + secret_keymd5_hash = hashlib.md5(sign_str.encode('utf-8')).hexdigest()return md5_hash

Step 3:验证码识别技术

3.1 获取验证码图片

验证码在登录过程中返回,URL例子:

https://internal.test/captcha/image?_t=时间戳

3.2 图片预处理与OCR识别

验证码为简单断码数字。使用Pillow处理,pytesseract识别。

示例预处理代码:

from PIL import Image, ImageFilter
import pytesseract
import io
import requestsdef get_captcha(session):url = f'https://internal.test/captcha/image?_t={int(time.time()*1000)}'response = session.get(url)img = Image.open(io.BytesIO(response.content))# 灰度化img = img.convert('L')# 二值化img = img.point(lambda x: 0 if x < 140 else 255, '1')# 去噪img = img.filter(ImageFilter.MedianFilter())return imgdef recognize_captcha(img):text = pytesseract.image_to_string(img, config='--psm 7 digits')text = text.strip().replace(' ', '')return text

Step 4:登录流程模拟

登录时需提交用户名、密码、验证码。

def login(session, username, password):# 获取验证码并识别captcha_img = get_captcha(session)captcha_text = recognize_captcha(captcha_img)login_data = {'username': username,'password': password,'captcha': captcha_text,}response = session.post('https://internal.test/api/login', data=login_data)result = response.json()if result['code'] == 0:print('登录成功')else:print('登录失败:', result['msg'])raise Exception('登录失败')

Step 5:核心数据接口调用

构造请求参数,调用数据接口:

def fetch_data(session, params):sign = generate_sign(params)post_data = {'param': params,    # 通常是原始参数JSON对象,部分实现会转换为字符串,请按实际情况调整'sign': sign,}headers = {'X-Custom-Token': 'token-from-cookie-or-js', # 需要通过登录等动态获取'Content-Type': 'application/json',}resp = session.post('https://internal.test/api/v1/getData', json=post_data, headers=headers)data = resp.json()if data['code'] == 0:return data['data']else:raise Exception(f"接口调用失败: {data['msg']}")

Step 6:整体爬虫流程整合

import requests
import timedef main():session = requests.Session()# 登录login(session, 'test_user', 'test_password')# 伪装UA头session.headers.update({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \(KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'})# 请求示例参数params = {'type': 'recent', 'limit': 20, 'timestamp': int(time.time())}# 调用接口data = fetch_data(session, params)print('获取数据:', data)if __name__ == '__main__':main()

总结

本案例通过模拟环境设计,综合讲述了下一些高级Python爬虫技术:

  • JavaScript逆向:理解并还原混淆及加密算法核心。
  • 签名构造:使用Python重现JS签名逻辑,成功通过接口认证。
  • 图形验证码识别:图像预处理加OCR,自动突破登录验证。
  • 会话管理:使用requests.Session维护登录态。
  • 爬虫实战:整合流程实现自动登录、数据抓取的完整爬虫。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91025.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91025.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/91025.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SQL】Windows MySQL 服务查询启动停止自启动(保姆级)

MySQL是一种开放源代码的轻量级关系型数据库管理系统&#xff0c;使用最常用的结构化查询语言&#xff08;SQL&#xff09;对数据库进行管理。由于MySQL具有体积小、速度快、成本低、开放源码等优点&#xff0c;现已被广泛应用于互联网上的中小型网站中&#xff0c;并且大型网站…

算法提升之数论(矩阵+快速幂)

通过矩阵和快速幂的方法来解决算法题目可以很好地降低时间复杂度&#xff0c;帮助大家更好地解决题目。下面这道题目有一定难度&#xff0c;希望大家可以好好地理解&#xff0c;相信对大家会有很大的帮助。问题描述有 n(2≤n≤10) 个玩家玩游戏&#xff0c;他们按 1 到 n 编号。…

数学建模算法-day[14]

6.2 传染病预测问题 问题提出 世界上存在很多传染病&#xff0c;如何根据其传播机理预测疾病得传染范围及染病人数等&#xff0c;对传染病的控制意义十分重大。 1.指数传播模型 基本假设 (1) 所研究的区域是一封闭区域&#xff0c;在一个时期内人口总量相对稳定&#xff0c;不考…

Linux救援模式之简介篇

什么是救援模式&#xff1f;救援模式提供了一个最小的Linux环境&#xff0c;通常只加载最基本的系统组件&#xff0c;允许管理员&#xff1a;修复损坏的系统恢复丢失的文件修改配置文件重置密码检查磁盘错误重新安装引导加载程序如何进入救援模式&#xff1f;1. 通过GRUB菜单进…

C++20实战FlamingoIM开发

C++20 与 Flamingo IM 实例 C++20 引入了许多新特性,如概念(Concepts)、协程(Coroutines)、范围(Ranges)等。Flamingo IM 是一个即时通讯项目,结合 C++20 的特性可以提升代码的可读性和性能。以下是基于 C++20 和 Flamingo IM 的实例。 协程实现异步网络通信 使用 C…

FPGA实现SRIO高速接口与DSP交互,FPGA+DSP异构方案,提供3套工程源码和技术支持

目录1、前言&#xff1a;SRIO在FPGADSP架构中的作用工程概述免责声明2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的FPGADSP异构方案我这里已有的 GT 高速接口解决方案3、工程详细设计方案工程设计原理框图FPGA端工程源码FPGA端SRIO从…

记一次导出pdf表单引发的问题

需求&#xff1a;点击按钮&#xff0c;将相关内容生成pdf下载下来问题1&#xff1a;之前项目封装好的下载文件方法不携带token 我尝试新写了一个方法&#xff0c;携带token问题2&#xff1a;此时出现了跨域问题 我分别尝试在controller类上和方法上加CrossOrigin(origins “*”…

AI-调查研究-39-多模态大模型量化 微调与量化如何协同最大化性能与效率?

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-30-新发布【1T 万亿】参数量大模型&#xff01;Kim…

基于Dify构建本地化知识库智能体:从0到1的实践指南

技术选型与方案设计 在企业级AI应用落地中&#xff0c;本地化知识库智能体已成为提升业务效率的核心工具。Dify作为低代码AI应用开发平台&#xff0c;结合RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;可快速构建私有化智能问答系统。以下是关键技术选型与架构设计…

C++与C#实战:FFmpeg屏幕录制开发指南

基于FFmpeg使用C#和C++开发 以下是一些基于FFmpeg使用C#和C++开发的简单屏幕录制软件示例,涵盖不同平台和功能需求。这些示例可作为学习或项目开发的起点。 使用C++开发FFmpeg屏幕录制 基础屏幕录制(Windows) #include <libavcodec/avcodec.h> #include <libav…

「源力觉醒 创作者计划」_DeepseekVS文心一言代码简单测试

一起来轻松玩转文心大模型吧一文心大模型免费下载地址&#xff1a;https://ai.gitcode.com/theme/1939325484087291906小插曲发现自己的上一篇文章的被盗了&#xff0c;而且是在deepseek上检索资料发现的&#xff0c;最让我破防的点在于&#xff0c;它完完全全搬运我的文章&…

服务器数据恢复—RAID上层部署的oracle数据库数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某公司一台服务器上有一组由24块FC硬盘组建的raid。 服务器出现故障&#xff0c;无法正常工作。 经过初步检测&#xff0c;管理员发现导致服务器故障的原因是raid中有两块硬盘掉线&#xff0c;导致卷无法挂载。服务器数据恢复过程&…

链表迭代翻转|二分|状态压缩bfs|数学

&#x1f36d;lc2039.bfs空闲时间把网络抽象成图&#xff0c;用 BFS 算出 0 号节点到各节点的最短距离 d 。结合每个节点发消息的间隔 patience[v] &#xff0c;先算消息往返需要 2d 秒。再看 2d 和 patience[v] 的关系若 2d 能被 patience[v] 整除&#xff0c;最后一条消息已发…

Vulnhub 02-Breakout靶机渗透攻略详解

一、下载靶机 下载地址&#xff1a;https://download.vulnhub.com/empire/02-Breakout.zip 下载好后使用VM打开&#xff0c;将网络配置模式改为net&#xff0c;防止桥接其他主机干扰&#xff08;桥接Mac地址也可确定主机&#xff09;。 二、发现主机 使用nmap扫描没有相应的…

数据结构(5)单链表算法题(中)

一、合并两个有序链表 1、题目描述 https://leetcode.cn/problems/merge-two-sorted-lists 2、算法分析 这道题和之前的合并两个有序数组的思路很像&#xff0c;创建空链表即可&#xff0c;可以很轻松地写出如下代码。 /*** Definition for singly-linked list.* struct L…

园区网络搭建实验

跟着B站上的老师&#xff0c;用华为ensp模拟搭建了一个园区网络&#xff0c;感觉挺好玩的虽然老师说这个很简单&#xff0c;但还是比我公司里的拓扑复杂LSW3配置上行端口3/4配置为串口&#xff0c;下行端口1/2为access口用于连接终端[Huawei]vlan batch 10 20 --创建vlan [Hua…

【tips】小程序css ➕号样式

上传的时候一般页面显示的是加号。不用图片可以用样式实现&#xff1b;wxss&#xff1a; /* 加号 */ .plus-box {width: 91rpx;height: 91rpx;border-radius: 6rpx;background: rgba(204, 204, 204, 1);position: relative; /* 用于定位加号 */ }/* 水平线条 */ .plus-box::bef…

MCU中的GPIO(通用输入/输出)是什么?

MCU中的GPIO(通用输入/输出)是什么? GPIO(General-Purpose Input/Output,通用输入/输出)是微控制器(MCU)或嵌入式系统中的一种可编程数字接口,用于与外部设备进行简单的高低电平信号交互。它是最基础、最常用的外设之一,广泛应用于按键检测、LED控制、传感器通信等场…

echarts 之 datazoom Y轴缩放

如果想 y 轴也能够缩放&#xff0c;那么在 y 轴上也加上 dataZoom 组件const dataZoomY ref([{type: "slider",yAxisIndex: 0,startValue: 0,endValue: 9,filterMode: "empty",width: 10,height: "80%",showDataShadow: false,left: 5,},{type:…

(四)Python基础入门-核心数据结构

概览 列表操作&#xff08;增删改查/切片/推导式&#xff09;元组特性与不可变性字典操作&#xff08;键值对/嵌套字典&#xff09;集合运算&#xff08;交集/并集/差集&#xff09; Python的核心数据结构是编程的基石&#xff0c;本文将系统讲解列表、元组、字典和集合四大数…