QQ音乐逆向工程 - 歌曲/歌词/评论API对接

30 节点 · 25 关系 · 7 分层 · 6 导览步骤

导览
分层
流程
统计

1. 🎯 起点:Python调度中心

main.py是所有数据获取的统一入口。从配置区设置song_mid/song_id/cookie,调用api_request统一发送请求,三个独立流程(get_lyric/get_comments/get_song_url)各司其职。理解main.py就理解了整体数据流。

2. 🔑 核心难点:JSVMP签名破解

sign.js包含从vendor.chunk.js提取的JSVMP虚拟机。getSecuritySign(明文body)是访问所有API的钥匙——没有它,所有请求都是废的。理解sign.js的JSVMP字节码解释器和环境补丁是逆向的核心。

3. 🔐 加密通道:AES-GCM + JSVMP双重加密

浏览器使用encoding=ag-1加密通道。请求AES-128-GCM加密,响应却用JSVMP自定义密码解密——这种不对称设计是个陷阱。幸好明文通道也能工作,加密通道留作备用。密钥已提取:bd305f10d0ff74b6ef54dab835b5e1cf。

4. ⚠️ 关键陷阱:双版本Vkey API

音乐下载最大的坑:新版GetEVkey即使cookie完全有效也返回104009,而经典CgiGetVkey稳定正常。不读DOMTRACE数据很难发现这个差异。CgiGetVkey需要filename参数(M500{songmid}.mp3),免费品质128kbps。

5. 📊 数据流:歌词+评论+歌曲三合一

三个独立数据流:歌词(base64 LRC解码)、评论(游标翻页采集,1秒间隔防限流)、歌曲(URL获取+流式下载)。所有请求共享同一个musics.fcg入口和sign签名机制。

6. 🔄 持久化:Cookie自动刷新

musickey每3天过期,但access_token有效期60天。通过QQLogin接口用token换新musickey,无需浏览器登录。更换后记得重新计算g_tk = hash5381(新musickey)。60天窗口内可无限刷新。

Python调度层

Python请求调度、数据解析、文件保存

main.py - P…hash5381(sk…api_request…get_lyric()…get_comment…get_song_ur…

Node.js签名层

JSVMP签名生成、CLI桥接

sign_server…sign.js - J…getSecurity…

加密通道层(备用)

AES-GCM加密/解密、第二段JSVMP字节码

crypto.js -…jsvmp2_raw.…AES-GCM加密通道…

API接口层

QQ音乐后端CGI接口

POST musics…vkey.GetVke…music.vkey.…music.music…music.globa…QQConnectLo…

业务流程层

端到端数据获取流程

Sign签名生成流程歌曲下载完整流程歌词获取流程评论翻页采集流程Cookie自动刷新流程

核心模块层

JSVMP虚拟机、环境补丁、DOMTRACE证据

JSVMP虚拟机保护JSVMP环境补丁DOMTRACE分析资料

文档与输出层

技术报告、参考手册、输出产物

REPORT.md -…请求链路.md - 请…SKILLS.md -…输出产物

Cookie自动刷新流程

musickey 3天过期,access_token 60天有效。刷新流程:用access_token+refresh_token+openid+musicid调用QQLogin接口→获取新musickey→重新计算g_tk(hash5381)→替换cookie。60天内可无限次刷新,无需浏览器登录。

入口: POST u6.y.qq.com/cgi-bin/musicu.fcg · http

Sign签名生成流程

明文JSON body → Python subprocess调用 → Node.js sign_server.js --sign → JSVMP getSecuritySign() → MD5变种哈希 → 'zzb'+40字符 → stdout → Python接收。完整链路:Python→Node.js→JSVMP→MD5→sign字符串。

入口: get_sign() in main.py · cli

歌曲下载完整流程

1.构建CgiGetVkey请求(含filename=M500{songmid}.mp3) → 2.生成sign → 3.POST musics.fcg → 4.解析响应获取purl+sip → 5.拼接完整URL → 6.HTTP GET流式下载 → 7.保存本地MP3。关键:使用CgiGetVkey而非GetEVkey,M500=MP3 128k免费。

入口: get_song_url() in main.py · http

歌词获取流程

1.构建GetPlayLyricInfo请求(songMID+songID) → 2.生成sign → 3.POST musics.fcg → 4.从req_1.data.lyric取base64字符串 → 5.base64解码 → 6.得到LRC格式歌词 → 7.保存lyric.lrc。

入口: get_lyric() in main.py · http

评论翻页采集流程

1.构建GetNewCommentList请求(BizType=1,BizId=songID,LastCommentSeqNo游标) → 2.生成sign → 3.POST musics.fcg → 4.解析CommentList → 5.提取Nick/Content/PraiseNum等字段 → 6.检查HasMore → 7.更新LastCommentSeqNo → 8.等待1秒 → 9.循环

入口: get_comments() in main.py · http
30
节点
25
关系
7
分层
6
导览

节点类型分布

function6
endpoint6
file5
module5
flow5
document3

项目信息

语言: Python, JavaScript, Node.js
框架: requests, JSVMP, AES-128-GCM
逆向QQ音乐Web端(y.qq.com)签名算法,完成歌曲下载、歌词获取、评论采集。核心难点:JSVMP虚拟机保护的sign算法、AES-GCM加密通道、双版本vkey API鉴权差异、Cookie自动刷新。复杂度:L3(多层壳+环境依赖)