尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python爬虫进阶:JS逆向从签名定位到参数复现的完整路线

Python爬虫进阶:JS逆向从签名定位到参数复现的完整路线 B站上那套“全748集 Python爬虫JS逆向全套进阶教程”最近又被顶到首页推荐位。标题确实让人热血沸腾2026最新版、七天从小白到大神、少走99%的弯路、学完即就业。但作为一个在爬虫和反爬对抗方向上折腾过不少项目的开发者我给正准备冲进去的朋友一个更冷静的判断这套视频真正值钱的不是“748集”这个数字而是它把一条完整的爬虫技术成长路线串了起来。你只要顺着这条路走确实能绕开大多数新手都会踩的坑但前提是你得动手而不是只看。Python爬虫入门确实不难。很多人花一个下午就能用 requests 抓到一个静态页面再简单清洗一下数据感觉自己已经“会爬虫”了。但真实业务场景里这类简单爬虫能覆盖的需求不到 20%。你很快会遇到三个致命问题请求参数被加密、页面由 JS 动态渲染、爬虫一放开频率就被限制。这三个问题恰好就是 JS 逆向这个方向要解决的事。所以这篇文章不打算逐集介绍视频内容而是顺着这套课程的核心骨架把 Python 爬虫和 JS 逆向的学习路线、必学知识点、工具链、最小可运行示例、常见坑位和工程实践一起梳理清楚。读完你可以拿它对照自己的学习进度也能直接照着跑通一个“从 requests 到 JS 加密参数复现”的最小链路。1. 爬虫开发者真正面临的三个问题先说一个很多入门教程不会告诉你的事实requests 写爬虫本质上只做了两件事——构造 HTTP 请求、解析 HTTP 响应。网页返回什么内容requests 就只能拿到什么内容。如果服务端把数据隐藏在一段 JS 加密逻辑后面你在 requests 层面再怎么加 headers、换 User-Agent 都没用。这也是为什么大量爬虫教程讲完 requests、BeautifulSoup、正则之后就不知道讲什么了。它们停在了最容易的部分。而 B 站这套课能分成 748 集恰恰说明它把重心放到了真正消耗时间和经验的深水区JS 逆向、加密参数分析、动态 Cookie、webpack 扣代码、AST 还原。这些内容才是爬虫岗位面试时真正会问的东西。我把爬虫开发者遇到的真实问题归纳为三类你可以拿自己的情况对照一下。1.1 静态网页容易动态参数难很多网站数据其实是通过 JSON 接口返回的浏览器里能看到完整数据但你在 Python 里重放请求时服务端返回 403、418 或者一个错误 JSON。原因是接口请求里带了签名参数比如sign、token、_signature这个参数是 JS 在浏览器本地算出来的没有它服务端就认为请求不合法。这类问题的解法只有一个方向把浏览器里生成参数的 JS 逻辑找出来然后用 Python 或 Node.js 重新实现一遍。这就是 JS 逆向的起点。1.2 单机爬虫容易规模化难入门时你写的爬虫是“跑一次就结束”的脚本。但工程化的爬虫要面对三个问题如何做增量采集而不是每次都全量重跑如何对同一类网站做垂直采集而不是每个网站单独写一套代码如何把请求任务分发到多台机器而不是单机死磕。对应到热搜词里的说法就是批量型爬虫、增量型爬虫和垂直型爬虫的应用场景。批量型解决一次性数据量很大的任务增量型解决每日更新的数据源垂直型解决某个特定行业或网站群的定向采集。这三类场景在学习阶段就应该有意识地区分否则你写出来的永远是“一次性脚本”。1.3 学完视频容易真正掌握难这句话不是泼冷水而是提醒。一套 748 集的视频如果真能“七天看完”大概率是倍速刷完的效果接近于零。正确用法是把它当字典和路线图遇到哪类问题就去查对应的集数跟着敲一遍再换一个真实目标练习一遍。真正的能力提升发生在你独立定位一个加密参数、独立补环境、独立扣出 webpack 模块、最后在 Python 里成功拿到合法数据的那一刻。视频只是地图走路的人还是你自己。2. 一套完整的爬虫知识体系应该怎么拆爬虫不是单一技术而是一条链路。从发起请求到最后入库每一环都可能出问题。这套 B 站课程之所以做得长是因为它把每个环节都展开讲了。下面按我自己的理解拆一下方便你按顺序学。2.1 Python 语法基础别追求全会优先学爬虫最常用的很多人一上来就刷 Python 教程刷到面向对象、装饰器、生成器就卡住了。其实爬虫初期用不到那么多语法你更需要掌握的是数据类型字符串、列表、字典、集合流程控制if、for、while函数定义与参数传递文件读写与 JSON 序列化异常处理给列表推导式、with 语句、requests 配合使用的常用模式把这些练熟就够了。面向对象、协程、装饰器可以在写 Scrapy 或更复杂框架时再补。先跑通爬虫链路再回来补语言深度学习效率会高很多。2.2 请求发送与管理requests、httpx 与 Sessionrequests 是最常用的 HTTP 库但要注意它不等于全部。遇到 HTTP/2 的网站、需要连接复用、异步请求的场景httpx 是更好的选择。Session 是新手容易忽略的东西。用requests.get每次都是独立连接而用requests.Session()可以保持 Cookie、连接池和默认 headers很多“登录后才能访问”的页面靠 Session 就能解决一大半。import requests session requests.Session() session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 }) # 先访问首页拿到初始 Cookie session.get(https://httpbin.org/cookies/set?namepython) # 再请求目标接口Session 会自动带上 Cookie resp session.get(https://httpbin.org/cookies) print(resp.json())这里真正容易踩坑的地方是如果目标网站的 Cookie 是由 JS 动态生成的Session 并不会自动帮你生成你需要先复现那一段 JS 逻辑然后把算好的 Cookie 手动塞进 Session。2.3 数据解析正则、XPath、CSS 与 JSONPath拿到 HTML 之后需要从里面提取目标数据。新手最容易上手的是正则但正则只适合结构简单的文本。嵌套标签多的时候用 XPath 或 CSS 选择器更稳定。推荐直接学 lxml 和 parselparsel 是 Scrapy 官方提取器语法和 Scrapy 一致以后写 Scrapy 不用重新学。from parsel import Selector html html body ul li classitem>from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() # 监听目标接口的响应 def handle_response(response): if api/list in response.url: print(response.json()) page.on(response, handle_response) page.goto(https://example.com) browser.close()注意无头浏览器是兜底方案不是最优解。原因很简单它消耗资源大、运行速度慢、容易被检测。真正高效的爬虫一定优先找接口把浏览器只用来辅助分析参数生成逻辑。2.5 数据存储文件、MySQL、MongoDB 与 Redis爬虫最后总要落到存储。简单任务用 CSV、JSON 文件就够了结构化数据量大时选 MySQL字段不确定、JSON 嵌套深的选 MongoDB需要频繁读写、去重、队列调度的场景用 Redis。import json # 示例保存为 JSON Lines 格式 data {title: Python爬虫, score: 9.2} with open(data.jsonl, a, encodingutf-8) as f: f.write(json.dumps(data, ensure_asciiFalse) \n)存储方案没有绝对好坏只要稳定、可恢复、便于清洗就行。但生产级爬虫一定要考虑增量去重否则每次全量跑会重复入库大量脏数据。2.6 调度与增量批量型、增量型、垂直型爬虫的应用场景前面提到的三类爬虫实际上对应不同的业务需求类型典型场景核心难点常用方案批量型一次性采集历史数据请求量大、速度控制多线程、分布式队列增量型每天抓取更新内容去重、断点续采Redis Set、数据库唯一索引垂直型针对特定平台持续采集解析规则维护、反爬变化灵活配置、模板化解析很多新手一上来就想要分布式爬虫其实在日数据量低于十万条时单机加 Redis 去重完全够用。分布式解决的是调度和带宽问题不是解析问题。把单机方案做到稳定高效比盲目引入一堆组件更实际。3. JS 逆向的核心难点与学习路径当 requests 环节解决不了加密参数时你就正式进入 JS 逆向的范畴了。这套 B 站课程最核心的内容也集中在后半段。下面我把这个方向拆开讲。3.1 为什么爬虫最终都会走向 JS 逆向反爬手段本质上是在校验“客户端是否可信”。校验方式可以放在 headers 里可以放在 Cookie 里也可以放在请求参数里。前两种还好办难的是第三种服务端要求每次请求都带一个动态计算的签名参数这个参数又只在浏览器端生成。这意味着你复现请求时必须把浏览器端生成参数的 JS 逻辑复制出来在 Python 或者 Node.js 环境里运行拿到同样的签名。这个“复制逻辑”的过程就是 JS 逆向。更准确地说是定位、调试、移植、补环境这四个步骤的循环。3.2 JS 逆向需要的前置知识不要零基础直接学 JS 逆向你会被各种术语劝退。先打三个底子JavaScript 语法变量、函数、闭包、原型链、异步浏览器调试控制台 Console、网络 Network、源码 Sources、XHR 断点常见加密算法Base64、MD5、SHA、AES、RSA至少要知道它们长什么样看完这套 B 站教程里对应的基础集数能看懂下面这段代码的水平再开始逆向比较合适。function md5like(input) { let raw String(input); let hash 0; for (let i 0; i raw.length; i) { hash (hash 5) - hash raw.charCodeAt(i); hash | 0; } return hash_ Math.abs(hash).toString(16); }这里真正容易误解的地方是你以为逆向是“破解”其实大部分情况下是“移植”。把别人的加密逻辑在本地跑通让参数合法这个过程和密码学破解没什么关系。所以它并不是不可学的技术而是一门熟练工技能。3.3 常见逆向目标与难度分级逆向目标常见表现核心手段难度请求参数签名URL 或 body 中出现 sign、token全局搜索、XHR 断点、调用栈回溯入门动态 Cookie第一次访问生成 Cookie第二次携带定位 Cookie 写入点、Hook入门请求体加密POST body 无法直接阅读找加密函数、补环境执行中等响应体解密接口返回密文字符串定位解密函数、逆向算法中等重度混淆变量名乱码、控制流平坦化AST 还原、反混淆高阶我建议的学习顺序是从签名参数开始再到动态 Cookie再到请求体加密和响应体解密最后才碰混淆。每一级都找一两个具体网站练手直到能完全脱离浏览器、在 Python 侧复现出合法参数。4. 环境准备与常用工具链无论你是看 B 站那套教程还是按本文路线自学工具链必须先准备好。下面是我推荐的“最小可用组合”。4.1 Python 环境与依赖安装建议使用 Python 3.8 及以上版本用venv创建虚拟环境。版本细节以你实际安装为准核心是不要污染系统 Python。python -m venv venv source venv/bin/activate pip install requests httpx parsel lxml pip install pyexecjs pip install playwright其中pyexecjs用于在 Python 中调用 JS 代码它是学习 JS 逆向时的好帮手。Playwright 用于动态页面辅助分析和模拟浏览器环境。4.2 浏览器调试面板Network、Sources、OverridesJS 逆向最重要的工具就是浏览器开发者工具。你重点要掌握四个面板Network查看所有请求找到带加密参数的接口Sources查看 JS 源码打断电跟踪变量变化Overrides可以覆盖本地 JS 文件方便修改源码调试Console执行临时 JS验证算法结果入门阶段80% 的定位工作是在 Network 和 Sources 之间来回切换完成的。4.3 抓包工具Fiddler、Charles 与 BurpSuite当爬虫目标不在浏览器里而是在 App 或桌面客户端里时就需要抓包工具。Fiddler 和 Charles 适合查看 HTTPS 明文流量BurpSuite 更适合做请求修改和重放。注意使用抓包工具调试他人系统时请确保你拥有该系统或已获得明确授权。本文提到的所有调试方法都只建议用于学习、测试和自己拥有的项目。4.4 Hook 与代码定位工具定位加密函数时除了搜关键词Hook 是更高效的思路。比如动态 Cookie 通常是通过document.cookie写入的你可以用下面这段代码在浏览器控制台里 Hook 住 Cookie 写入点刷新页面后看控制台输出就能定位到写入参数的那一行。(() { const originalCookie document.cookie; Object.defineProperty(document, cookie, { get() { console.trace(cookie 被读取); return this.__cookie || ; }, set(value) { console.log(cookie 被写入:, value); this.__cookie value; return value; } }); })();这只是学习阶段的调试技巧请在你自己可控的页面环境中使用。4.5 执行 JS 的环境Node.js、PyExecJS、PyMiniRacer拿到一段加密 JS 后你需要在本地环境运行它。常见方式有三种方式优点缺点适用场景Node.js 直接运行兼容性最好需要手动安装依赖复杂 JS、扣 webpack 模块PyExecJS 调用Python 内直接执行性能一般、环境配置容易出问题简单算法、学习验证PyMiniRacer嵌入 V8 引擎跨平台安装有门槛对性能有一定要求的场景最稳妥的方案是把逆向得到的 JS 整理成独立文件先用 Node.js 调通再在 Python 中通过 subprocess 或 HTTP 服务调用。这样两边职责清晰问题也好排查。node -e const fn require(./encrypt.js); console.log(fn.makeSign({page:1}))5. 完整示例与代码实现下面用一个最小链路走一遍先用 requests 请求一个公开页面再模拟“定位加密参数”的过程最后在 Python 里调用 JS 生成签名参数。注意示例不是针对任何真实网站仅用于讲解流程。5.1 示例一用 requests 完成基础 HTTP 请求# 文件路径demo_requests.py import requests url https://httpbin.org/html headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } resp requests.get(url, headersheaders, timeout10) print(状态码:, resp.status_code) print(响应前500字:, resp.text[:500])运行命令python demo_requests.py如果看到200和 HTML 内容说明环境正常。这一步的目的是确认 requests 可以正常发送请求并拿到响应。5.2 示例二模拟定位加密参数的调试流程在分析真实网站时你会遇到类似这样的签名函数。假设你通过全局搜索或断点找到了生成sign的逻辑并整理成一个独立的 JS 文件。// 文件路径encrypt.js // 说明这是教学示例用一个简单散列模拟真实加密函数的定位结果 function makeSign(params) { let raw Object.keys(params) .sort() .map((k) k params[k]) .join(); let hash 0; for (let i 0; i raw.length; i) { hash (hash 5) - hash raw.charCodeAt(i); hash | 0; } return sign_ Math.abs(hash).toString(16); } module.exports { makeSign };在真实场景里这一步通常是“找到加密函数——打断点——跟踪入参——复制逻辑——整理成模块”的循环。上面这个文件就相当于你整理出来的结果。5.3 示例三在 Python 中调用 JS 生成签名并附加到请求接下来用execjs在 Python 中调用刚才的 JS 模块# 文件路径demo_sign.py import execjs import requests # 1. 读取并编译 JS 文件 with open(encrypt.js, r, encodingutf-8) as f: js_code f.read() ctx execjs.compile(js_code) # 2. 构造业务参数 params { page: 1, limit: 20, ts: 1700000000, } # 3. 调用 JS 里的 makeSign 方法生成签名 sign ctx.call(makeSign, params) params[sign] sign print(生成的签名:, sign) # 4. 将签名参数附加到请求中 url https://httpbin.org/get resp requests.get(url, paramsparams, timeout10) print(请求URL:, resp.url) print(状态码:, resp.status_code)运行命令python demo_sign.py如果能看到生成的签名和200状态码说明整条链路已经打通requests 发请求JS 生成加密参数Python 侧完成参数注入。真实项目里你只需要把encrypt.js替换成实际逆向得到的文件再根据接口要求调整参数位置即可。这段链路的价值在于它把爬虫和 JS 逆向真正连接起来了。很多人学完 requests 不知道怎么用 JS 逆向学完 JS 逆向不知道怎么回爬虫上面这个示例刚好把缺口补上。6. 运行结果与效果验证运行示例一后预期输出类似状态码: 200 响应前500字: !DOCTYPE html...看到200说明网络环境和 Python 环境没有问题。运行示例三后预期输出类似生成的签名: sign_2a7c1f3e 请求URL: https://httpbin.org/get?page1limit20ts1700000000signsign_2a7c1f3e 状态码: 200验证是否成功看三个地方签名是否稳定生成相同输入应该得到相同签名不同输入签名应发生变化。签名是否成功拼到 URL 或 body 中检查打印出的请求参数。服务端是否接受请求返回 200 说明签名校验通过返回 403 或参数错误则还需要调整。如果失败第一步先看execjs环境是否正常python -c import execjs; print(execjs.get().name)如果输出的是Node.js (V8)说明 PyExecJS 能正常找到 JS 运行时。如果报找不到运行时就需要安装 Node.js 并确认它已加入环境变量。7. 常见问题与排查思路结合大量初学者的提问我把高频问题整理成下表你可以直接对照排查。问题现象可能原因排查方式解决方案requests 直接访问返回 403/418缺少浏览器 headers 或 Cookie对比浏览器请求头差异补全 User-Agent、Referer、Cookie或先用 Session 访问首页浏览器能打开requests 拿不到数据数据由 JS 动态渲染在 Network 中查找 XHR 接口优先分析接口而不是解析 HTML定位不到加密参数生成位置搜索关键词不对搜索参数名、XHR 断点、事件监听用全局搜索搜sign、token等关键词再结合调用栈JS 在浏览器正常在 execjs 报错缺少浏览器环境变量查看报错是否出现window、document在 JS 中模拟window和document或改用 Node 补环境动态 Cookie 生成失败Cookie 在首次响应中生成依赖后续 JS 计算观察首次请求和后续请求的 Cookie 差异用浏览器无头模式辅助生成再手动注入 Session请求频率一高就被限制缺少限速和代理策略看服务端返回异常码的时间节点加入随机延时、重试机制、代理池控制请求频率扣下来的 webpack 模块无法运行缺少模块导出或调用入口检查模块导出方式和调用上下文找到模块的入口函数补全导出对象后在 Node 中启动这里真正容易踩坑的地方是“补环境”。很多 JS 代码在浏览器里能跑是因为它依赖window、document、navigator这些浏览器对象。到了 Node 或 PyExecJS 里这些对象不存在代码就会报错。解法不是把整个浏览器都模拟出来而是只补报错缺失的那几个变量。8. 最佳实践与工程建议前面讲的是“怎么跑通”这一节讲的是“怎么跑得稳”。在真实项目中爬虫和 JS 逆向的稳定性往往比功能本身更重要。8.1 合规是底线爬虫采集必须遵守目标网站的 robots 协议、服务条款和相关法律法规。学习 JS 逆向时优先选择自己拥有、自己部署或明确允许测试的网站。不要用逆向技术去窃取账号信息、绕过付费或访问未授权数据。这篇文章里的所有调试技巧都只能用于合法授权的学习环境。无论技术学到什么程度合规意识都要走在前面。8.2 逆向代码与业务代码分离不要在一堆业务代码里塞execjs.call。建议把 JS 文件放在独立的js/目录里用一个sign_client.py封装签名生成逻辑业务侧只调用函数不感知内部实现。project/ ├── js/ │ └── encrypt.js ├── crawler/ │ └── sign_client.py ├── demo_requests.py └── demo_sign.py这样当目标网站更新算法时你只需要替换 JS 文件、调整封装层业务代码基本不用动。8.3 限速、重试与代理池请求太快是爬虫被封的第一原因。建议在代码里加入随机延时并用指数退避策略处理临时性失败。import time import random def get_with_retry(session, url, max_retry3): for attempt in range(max_retry): try: resp session.get(url, timeout10) if resp.status_code 200: return resp except Exception: pass time.sleep(random.uniform(1, 3) * (attempt 1)) return None代理池不是必须的只有当目标网站对 IP 有严格限制时才考虑。先用限速和重试解决大部分问题。8.4 日志、监控与数据校验生产环境里的爬虫要能“自证清白”。每次请求记录时间、目标、状态码和耗时每条数据入库前做字段校验防止字段缺失导致脏数据污染整个表。import logging logging.basicConfig( levellogging.INFO, format%(asctime)s %(levelname)s %(message)s, handlers[ logging.FileHandler(crawler.log, encodingutf-8), logging.StreamHandler() ] ) logging.info(请求成功: %s, url)一个看似麻烦的日志习惯在排查“为什么数据少了三分之一”这种问题时能救你一次。8.5 不要把全部希望寄托在“扣代码”JS 逆向确实能解决很多问题但它不是唯一方案。有些场景下用无头浏览器监听接口、或者通过合法 API、官方数据开放平台可能比逆向更稳定。学会评估投入产出比是工程师和脚本小子的分水岭。9. 总结与后续学习方向回到开头那套 B 站教程。如果你问我它到底值不值得看我会说值得但不要把“748 集”和“七天从小白到大神”当回事。它的真正价值是一张完整的地图Python 基础、requests、数据解析、Scrapy、JS 逆向、动态 Cookie、webpack 扣代码、AST 还原每一步都有对应的章节。你只要按图索骥再结合自己的目标项目练习就能走出一条比“到处找零散教程”高效得多的路。这篇文章帮你做的是把这条路线抽象成了可执行的框架先解决请求与解析再进入 JS 逆向最后落到工程化和合规。建议你按下面的顺序继续实践把示例一和示例三跑通确保 requests、parsel、execjs 环境正常。找一个自己拥有或授权的简单网站尝试用浏览器开发者工具定位一个签名参数。把签名参数对应的 JS 逻辑整理成独立文件在 Python 中调用并请求成功。再看 B 站教程里对应的 JS 逆向章节补上 webpack、AST 等进阶内容。后续值得继续深入的方向还有AST 混淆还原、JS RPC 远程调用、安卓逆向如果你以后要做 App 采集、Scrapy 分布式爬虫以及用 AI 辅助逆向定位加密逻辑。每一个方向都能单独写几篇长文但前提都是先把这条最小链路跑熟。爬虫这条路门槛不高天花板不低。真正决定你能走多远的不是看过多少集视频而是独立解决过多少个“浏览器能跑、Python 不能跑”的问题。先动手再把坑一个一个踩平你的爬虫能力就会在这个过程中真正长出来。
返回列表