news 2026/8/30 18:21:11

Python爬虫与JS逆向实战:从请求到加密参数解析的完整路线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python爬虫与JS逆向实战:从请求到加密参数解析的完整路线

先给一个直接判断:这套Python爬虫和JS逆向的学习内容,核心不是让你背几百个API名字,而是帮你建立一条完整的链路——从发一个HTTP请求、拿到HTML或JSON,到解析数据,再到面对动态页面、加密参数时能自己定位问题并复现逻辑。它适合三类人:刚学完Python基础、想做数据采集的初学者;前端和后端都想碰一碰的全栈学习者;以及工作中经常要对接网页数据、处理接口签名或排查前端逻辑的工程师。最值得关注的不是“748集”这个数量本身,而是这些内容到底按什么顺序学、学到什么程度能真正动手。

我见过太多人把精力花在“收藏教程”和“复制代码”上,结果真遇到一个动态加载的页面还是不知道从哪里下手。问题通常不在代码量,而在于学习顺序和排查思路。下面我按自己实际带项目时会用的顺序,把这套知识拆开讲一遍。重点不是帮你“七天速成”,而是告诉你哪些环节必须花时间、哪些环节可以先跳过,以及每一步怎么验证自己真的学会了。

1. 先搞清楚爬虫和JS逆向到底在解决什么问题

1.1 爬虫解决的是数据获取效率问题

爬虫的本质很简单:用程序代替人工,批量、自动地从网页或接口获取数据。它解决的问题不是“能不能拿到数据”,而是“能不能稳定、快速、按规则地拿到数据”。

一个典型流程包括四步:

  1. 构造请求:明确目标地址、请求方法、请求头和参数。
  2. 获取响应:拿到HTML、JSON、图片、文件等原始内容。
  3. 解析数据:从响应中提取需要的字段。
  4. 存储和后续处理:保存到数据库、表格或文件,再进入分析流程。

这四步听起来简单,但每一步都有坑。比如请求头少了一个字段可能直接被拒绝,编码不对可能解析出来全是乱码,页面结构一变解析逻辑就失效。所以学爬虫不光是学requests和BeautifulSoup怎么用,更重要的是学会“看现象、定位原因、验证结果”。

1.2 JS逆向不是“破解”,而是理解请求参数的生成逻辑

很多人一听到JS逆向就觉得是跟网站安全对抗。实际在工程场景里,它的核心任务是:当你发现某个数据接口的请求参数里有一个加密字段,比如signtokencookie中经过计算的变量,你要去浏览器前端代码里找到这个字段是怎么生成的。

这个动作本身是前端调试和接口联调的基本功。无论是排查自己网站的接口问题,还是分析一个第三方公开页面里的数据加载逻辑,你都需要能顺着网络请求找到对应的JavaScript代码,看懂参数从哪里来、经过了什么函数、最后怎么变成请求里那个字符串。

所以JS逆向更准确的说法是“前端请求逻辑分析”。它用到的技术包括:

  • 浏览器开发者工具的Network、Sources、Console面板。
  • 断点调试、调用栈分析、变量监视。
  • 常见编码和加密算法的识别。
  • 用Python或Node.js把前端逻辑重新实现一遍。

1.3 这套技能真正适合谁学

如果你属于下面这些情况,爬虫和JS逆向就值得投入时间:

  • 想采集自己认可的数据源,用于学习、分析或个人项目。
  • 需要对接某些网页接口,但官方API不完整或没有。
  • 做全栈开发,想理解前端加密、请求签名和后端校验的配合方式。
  • 做数据分析和可视化,需要定期从公开页面汇总数据。

但必须明确一个前提:爬虫要在合规范围内使用。尊重网站的robots.txt、服务条款和数据使用政策,控制请求频率,不采集个人隐私数据,不攻击或绕过正常的安全机制。这不是套话,而是实际做项目时避免麻烦的基本底线。

2. Python环境与网页抓取入门,先把最小流程跑通

2.1 环境准备:Python、IDE、依赖库

要想少踩环境坑,先把这套基础环境装好。我建议按下面的顺序操作,每完成一步就验证一次,不要一口气全装完再报错。

第一步:安装Python。

  • Windows用户到Python官网下载安装包,安装时务必勾选“Add Python to PATH”。
  • macOS用户可以用官方安装包,也可以使用Homebrew安装。
  • Linux用户多数发行版自带Python 3,但版本可能偏旧,建议用系统包管理器安装较新版本。

安装完成后,在命令行执行:

python --version

能正常输出版本号,说明环境变量没问题。如果提示“python不是内部或外部命令”,多半是安装时没勾选PATH,重新安装一次即可。

第二步:安装IDE。

推荐VS Code,免费、跨平台、插件丰富。装好后再安装Python扩展插件,就能获得代码补全和调试能力。也可以用PyCharm Community版,对新手更友好,但启动速度慢一些。

第三步:创建虚拟环境并安装依赖库。

我的习惯是每个项目单独建虚拟环境,避免依赖版本冲突。终端里执行:

python -m venv venv

Windows激活命令:

venv\Scripts\activate

macOS和Linux激活命令:

source venv/bin/activate

然后安装最常用的几个库:

pip install requests beautifulsoup4 lxml
库名作用
requests发送HTTP请求,获取响应
beautifulsoup4解析HTML,提取数据
lxmlBeautifulSoup的解析引擎,速度快

注意:这里不要急着装selenium、playwright这些浏览器自动化库。先把requests跑通,后面发现确实需要再装。

2.2 一条最简单的抓取流程

装好环境后,先写一个最小样例。用requests请求一个页面,用BeautifulSoup提取标题。

import requests from bs4 import BeautifulSoup url = "https://example.com" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36" } resp = requests.get(url, headers=headers, timeout=10) print(resp.status_code) soup = BeautifulSoup(resp.text, "lxml") print(soup.title.text)

这里有几个关键点:

  • headers里特意加了User-Agent,是因为很多服务器会拒绝默认的Python客户端标识。
  • timeout=10表示最多等10秒,避免请求卡死。
  • resp.status_code先打印状态码,200表示成功,403或418通常说明被拒绝。
  • soup.title.text取出页面标题,先确认HTML能被正确解析。

不要小看这几行代码。它能跑通,说明你的环境、请求、解析环节全部正常。后面所有复杂逻辑都是在它的基础上叠加的。

2.3 怎么判断结果是“正确的”

跑通一次不等于写对了。我一般用三个标准检查:

  1. 状态码是否合理:200是正常,304是缓存,403、429、5xx都需要排查。
  2. 内容是否符合预期:标题、正文、列表数据是否和浏览器里看到的一致。
  3. 数据完整性:数量对不对、字段有没有缺失、特殊字符和编码是否正确。

如果只是打印出一段乱码,先检查resp.encoding,并尝试:

resp.encoding = resp.apparent_encoding

或者直接用resp.textresp.content对比。resp.content拿到的是原始字节,resp.text是按编码解码后的字符串。中文乱码时,通常优先用resp.apparent_encoding重新设置编码。

3. 动态页面才是分水岭,先看懂网络请求再动手

3.1 静态HTML和动态接口的区别

早期网页大部分是服务端渲染,HTML里直接包含所有数据。爬虫只要请求一个URL,解析HTML就能拿到全部内容。

现在的网页大量采用前后端分离。浏览器打开页面时先加载一个HTML壳,然后通过JavaScript去请求后端接口,再把数据渲染到页面上。这种页面你在爬虫里用requests直接请求,得到的HTML往往只有空壳,真正的数据在接口的JSON响应里。

判断一个页面是静态还是动态,方法很简单:在浏览器里右键“查看网页源代码”,搜索你关心的数据。如果在源码里能找到,那就是静态网页;如果找不到,说明数据是动态加载的,要去Network面板找真实接口。

3.2 用浏览器开发者工具定位真实数据接口

以Chrome为例,按F12打开开发者工具,切到Network面板,刷新页面,然后下拉页面触发新数据加载。

这时候你会看到大量请求,重点看XHR和Fetch类型的请求。它们通常返回JSON数据,格式清晰,是爬虫最理想的取数目标。

在请求列表里点击某个请求,右侧可以看到:

  • Headers:请求URL、请求方法、请求头、查询参数。
  • Payload:POST请求提交的JSON或表单数据。
  • Response:服务器返回的原始内容。
  • Preview:格式化后的JSON预览。

我的经验是:先按返回内容过滤,再按名字找接口。大多数接口URL包含apilistdatasearch等关键字,一眼就能判断是不是目标接口。

找到数据接口后,先在浏览器里复制请求为cURL格式,再用在线工具转成Python代码,能快速验证接口是否可以直连。但要注意,有些接口会在请求头或参数里做校验,直接requests可能失败,这时候才进入JS逆向分析的环节。

3.3 什么时候直接用requests,什么时候需要浏览器自动化

这是新手最容易纠结的问题。我的判断标准很简单:

  • 数据接口的URL和参数都能在网络请求里看到,且直接用requests发送能成功,那就用requests。性能最好,代码最简单。
  • 数据加载高度依赖JavaScript执行,比如需要模拟点击、滚动、登录后才能出现,且接口层做了较复杂的参数校验,再考虑用selenium或playwright。
  • 如果用浏览器自动化,最推荐的其实是playwright。它比selenium更现代,自带等待机制和截图能力,而且支持异步。

但浏览器自动化是最后手段,不是首选。因为它吃内存、速度慢、还容易因为页面结构和元素变化而崩。真正的工程实践里,requests加适当的接口参数模拟才是主流。

先requests,再接口分析,最后才上浏览器自动化。

4. JS逆向的完整排查思路:从参数到逻辑

4.1 先确定要逆向的对象是谁

进入JS逆向分析前,先别急着打开Sources面板。我建议你先回答三个问题:

  1. 哪个请求被拒绝了?状态码是多少?
  2. 这个请求的哪个参数是动态变化的?
  3. 这个参数在两次请求中的值是否不同?

只有确认了“某个参数每次变化,且服务器会校验”,才值得分析。有些时候你只要把请求头补全、把cookie带上就能成功,根本不需要碰JS。

定位动态参数的方法:在Network面板里找到目标请求,看它的Query String Parameters或Form Data。如果某个参数的值是一长串字母数字,且每次刷新都变,那它很可能就是校验参数。

4.2 用断点追踪参数的生成位置

确定目标参数后,在Sources面板里按Ctrl+Shift+F全局搜索参数名。比如参数叫sign,搜索后可能得到多个结果,优先看JS文件里赋值的位置。

更常用的方式是搜索参数名字符串,然后打断点。步骤如下:

  1. 点击搜索结果进入对应的JS文件。
  2. 在赋值语句那行打上断点。
  3. 回到页面刷新,触发数据请求。
  4. 当代码停在断点处,单步执行,查看变量值变化。

观察调用栈(Call Stack)也很关键。它能告诉你这个函数是从哪里被调用的,前面经过了哪些函数。顺着调用栈往下找,通常能找到参数生成的最源头。

这个环节最考验耐心。不要指望一分钟就找到,一个参数从生成到赋值可能要经过好几个函数。我一般会先关注那些名字和加密、签名相关的函数,比如包含encryptsigntokenmd5sha等关键字的函数。

4.3 常见的加密算法特征和识别方式

前端常见的加密和编码手法就那么几类,识别出来以后,Python里复现并不难。

类型特征常见场景
Base64末尾常见=,字符集为字母数字和+/简单编码,肉眼可见
MD5固定32位十六进制字符串请求签名、摘要
SHA1/SHA256固定40位或64位十六进制字符串签名、完整性校验
AES需要密钥和IV,加密结果通常有固定块长度请求参数加密、响应内容加密
RSA需要公钥,加密结果较长登录密码加密

识别方法可以先看长度和字符集。32位十六进制多半是MD5,64位可能是SHA256。带=的是Base64。如果JS文件里出现CryptoJS,那大概率是AES或SHA系列。

这里必须先说明:如果你要分析的接口是你有权限访问的,或者是你自己在开发维护的系统,理解加密逻辑是正当的排查工作。如果你试图绕过别人设置的安全校验做大规模采集,那就属于越界了。学习阶段建议用公开的教育型Demo站,或者自己搭建一个带签名校验的测试服务来练习。

4.4 在Python里复现并验证

找到算法后,在Python里复现,通常用hashlibbase64Crypto等库。以MD5签名为例:

import hashlib def make_sign(data: str) -> str: md5 = hashlib.md5() md5.update(data.encode("utf-8")) return md5.hexdigest() print(make_sign("hello"))

AES加密则可以用pycryptodome库。复现后,拿你从浏览器里看到的原始参数值做对照,如果Python生成的结果和浏览器JS生成的结果一致,就说明算法和密钥都对上了。

验证步骤我建议固定为三步:

  1. 用已知输入跑一遍Python实现,确认输出和浏览器一致。
  2. 把生成的参数放到requests请求里,确认服务器接受。
  3. 连续请求多次,确认每次生成的参数都不同且都有效。

只有第三步也通过,才算真正搞定。否则可能只是偶然匹配上。

5. 单条任务稳定后,再设计批量、增量和数据落地

5.1 批量任务要先解决命名、限速和失败重试

单条任务跑通后,很多人直接写一个for循环批量跑,结果跑了一半被限制,或者输出文件互相覆盖。这里最容易踩的坑有三个:

第一是输出命名。批量任务必须有唯一文件名。我习惯用“时间戳+业务标识”的方式:

from datetime import datetime timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"data_{timestamp}_{page}.json"

第二是限速。不要一上来就开最大并发。requests版本可以先串行,每次请求之间加一个随机间隔:

import time import random time.sleep(random.uniform(1, 3))

间隔的意义不只是降低服务器压力,也是让采集行为看起来更接近正常访问频率。如果是并发版本,用ThreadPoolExecutor也要控制最大线程数,建议先从2到4个开始。

第三是失败重试。网络请求一定会失败,这不是概率问题,是时间问题。所以要写重试逻辑。一个简单的通用做法:

def fetch_with_retry(url, headers, retries=3): for i in range(retries): try: resp = requests.get(url, headers=headers, timeout=10) if resp.status_code == 200: return resp except requests.RequestException as e: print(f"第{i+1}次失败: {e}") time.sleep(2) return None

重试要注意退避策略。连续失败后间隔越来越大,避免给服务器造成持续压力。

5.2 增量爬虫关注的是变化检测和去重

增量爬虫解决的是“反复跑同一批任务”的问题。它和批量爬虫的核心差异在于:批量爬虫每次处理完整的任务列表,增量爬虫只处理新增或变化的数据。

在爬虫领域,这三类应用场景经常被拿来对比:

  • 批量型爬虫:一次性采集大量历史数据,适合冷启动。
  • 增量型爬虫:定期检查页面变化,只采集新增、删除或修改的数据,适合持续监控。
  • 垂直型爬虫:专注于某个特定领域或网站,比如新闻、商品、行业报告,通常把批量采集和增量更新结合起来。

实现增量爬虫时,关键是要有“去重依据”。最简单的做法是记录每条数据的唯一ID或URL,下次跑之前先查一下是否已经处理过。数据量小时用集合记录即可:

seen_ids = set() def process_item(item): if item["id"] in seen_ids: return seen_ids.add(item["id"]) # 保存数据

数据量变大后,可以用数据库的唯一索引,或者用布隆过滤器判断是否重复。判断标准很简单:同一批数据反复跑,不产生重复记录;源数据更新后,新的记录能正常进入结果集。

5.3 数据保存和日志管理

采集到的数据最终要落盘。小规模学习场景用JSON或CSV足够,生产环境建议入数据库,比如SQLite、PostgreSQL或MongoDB。

保存数据时注意编码问题。写入CSV时建议指定utf-8-sig,否则用Excel打开会乱码。写入JSON时建议设置ensure_ascii=False,这样中文不会变成\u转义符:

with open("data.json", "w", encoding="utf-8") as f: json.dump(all_data, f, ensure_ascii=False, indent=2)

日志是另一个容易忽略的点。批量任务跑起来以后,你不可能一直盯着终端。必须把关键信息写入日志文件,包括:

  • 每条请求的开始时间、URL、状态码。
  • 失败重试的次数和原因。
  • 每次运行的总数、成功数、失败数。

有了日志,任务卡住时才能快速定位。我看到很多新手出问题时第一反应是“代码哪里写错了”,实际上先看日志、看输出目录、看资源占用,往往比猜代码更高效。

6. 常见报错和排查链路,按顺序查能省一半时间

6.1 请求层:状态码、超时、请求头

请求失败是最常见的报错,按下面的顺序排查。

403 Forbidden:多半是请求头不完整。补上User-AgentRefererOrigin等字段,先从浏览器Network面板里复制完整请求头,再逐项补到代码里。

429 Too Many Requests:请求频率太高被限流了。降低频率,等待一段时间恢复,不要反复重试。

超时:可能是网络问题,也可能是服务器响应慢。先尝试调大timeout,再看目标URL是否真的可以访问。

Invalid URL 或 MissingSchema:URL没写完整,少了https://

SSL证书报错:少数网站证书有问题,可以在requests里设置verify=False,同时忽略警告:

import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) resp = requests.get(url, headers=headers, verify=False)

verify=False只用于调试,生产环境不要随意关闭证书校验。

6.2 解析层:编码、结构变化、空数据

请求成功但解析不到数据,先看resp.text的内容。如果是一大段乱码,先处理编码。如果内容是空壳HTML,说明数据是动态接口加载的,回到第三部分去找真正的接口。

如果之前能解析,今天突然解析不到,最常见的两个原因是:

  1. 页面结构改版了:CSS选择器失效。需要重新打开页面看新的结构。
  2. 数据加载方式变了:原来是接口返回,现在变成了别的格式。

解析HTML时,我建议先用浏览器开发者工具复制选择器,但不要完全相信它。很多复制出来的选择器包含动态class,下次页面更新就会失效。更稳妥的做法是选择相对稳定的属性,比如id>

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 18:21:02

Python爬虫工程化指南:从工具选型到批量任务部署

这次直接聊一个很多读者后台催更的话题:Python 爬虫。很多人问我有没有值得看的开源项目,其实每次打开 GitHub 趋势榜,爬虫相关的新项目都会冒出来几个,有的偏数据采集框架,有的偏浏览器自动化,有的干脆是现…

作者头像 李华
网站建设 2026/8/30 18:20:57

基于PHP+MySQL的教材管理系统设计与实现全解析

简介:在信息化教学管理中,教材管理涉及申购、审核、入库、发放等多个环节,是典型的中小型管理信息系统。基于ApachePHPMySQL这一经典Web开发组合,开发者可快速构建业务逻辑清晰的系统,其底层涉及数据库设计、事务处理、…

作者头像 李华
网站建设 2026/8/30 18:13:57

拒绝逆向工程,小程序安全开发与合规实践指南

抱歉,我不能帮助进行任何形式的逆向工程或帮助绕过应用程序的安全措施。逆向分析他人小程序涉及违反服务条款、潜在的版权问题以及隐私和安全风险。如果你想学习移动应用开发或安全开发实践,我可以帮助你了解以下合法合规的主题:微信小程序的…

作者头像 李华
网站建设 2026/8/30 18:09:01

软件测试太卷?不如转向嵌入式、芯片与机器人测试

“软件测试卷到失业”在最近不是一句玩笑话。很多人从功能测试、接口测试一路做到管理岗,突然发现自己引以为傲的经验,正在被越来越多的外包团队、自动化平台和 AI 工具压缩价值。而另一边,嵌入式测试、芯片测试、机器人测试的岗位需求却在持…

作者头像 李华
网站建设 2026/8/30 18:08:06

自动化测试落地路径:分层、选型与稳定脚本实战

自动化测试不只是一门工具使用课,它本质上是一套质量保障流程:把重复的人工点击、输入、校验、比对行为,固化成可以反复执行、自动判断结果、随时回归复用的脚本能力。对刚入行的测试工程师、想转测试的开发,以及准备搭建自动化测…

作者头像 李华
网站建设 2026/8/30 18:07:04

Discuz AIUI手机模板V7.3.0:提升移动端体验与SEO优化的完整指南

简介:响应式布局是现代Web开发的核心概念,它通过CSS媒体查询等技术,使网页能够自动适配不同尺寸的屏幕设备。其原理在于根据视口宽度动态调整页面结构、图片和字体大小,确保在手机、平板等移动设备上获得良好的浏览体验。这项技术…

作者头像 李华