蜻蜓FM音频链接解析与签名生成实战教程
前言本次教程围绕音频站点的音频链接解析展开全程贴合实战抓包、逆向分析、代码实现的完整流程手把手拆解音频链接的拼接、加密签名逻辑最终实现自动化获取可播放的音频地址。本文仅用于编程学习与逆向分析技术交流切勿用于商业盈利、非法爬取等违规违法用途。一、前期排查定位有效音频源1.1 抓包筛选音频文件首先打开目标音频播放页面按下F12开启浏览器开发者工具切换到Network网络面板刷新页面开始抓包。在筛选栏中过滤媒体文件重点排查m4a、mp3等常见音频格式的请求链接找到页面对应的音频资源请求。此时会看到大量网络请求我们需要甄别出真正的音频播放链接这类链接通常带有音频标识、时长参数且请求头对应音频资源类型。1.2 验证链接有效性找到疑似音频链接后直接复制链接到浏览器地址栏打开若链接能够正常播放、下载音频文件说明成功定位到了有效的音频源这一步是后续解析的基础确保我们找对了目标链接避免做无用功。二、URL结构分析拆解链接参数2.1 完整链接格式拆解拿到可播放的音频链接后先对链接格式进行拆分观察其组成部分示例格式如下https://xxx.xxx.cn/audiostream/redirect/频道ID/音频ID?access_tokendevice_idMOBILESITEqingting_idt时间戳sign签名字符串通过拆解可以清晰分出几部分域名前缀、接口路径、节目ID、音频ID、请求参数、签名参数。2.2 各参数作用分析域名前缀音频资源的服务器域名固定不变频道ID节目ID对应专辑、节目的唯一标识页面内固定音频ID单集音频的唯一标识每一集音频对应不同IDaccess_token用户凭证参数实测为空值即可device_id设备标识固定为MOBILESITE是关键定位线索qingting_id用户标识参数实测为空值即可t时间戳防止链接缓存每次请求动态生成sign加密签名校验链接合法性核心加密参数不难发现除了动态的音频ID、时间戳和签名其余参数大多固定或为空而sign是接口校验的核心必须通过加密算法生成否则链接无法访问。三、定位加密代码找到加密逻辑在分析完URL参数后我们需要找到生成sign签名、拼接音频链接的JS代码这里利用固定参数MOBILESITE作为突破口。回到浏览器开发者工具切换到Search搜索面板全局搜索关键词MOBILESITE这个参数是固定不变的能精准定位到拼接音频链接、生成签名的JS代码块。搜索后即可找到对应的加密逻辑代码这段代码包含了参数拼接、签名生成的完整逻辑能清晰看到签名采用的加密方式、密钥以及签名字符串的拼接规则。四、加密逻辑还原补全代码逻辑4.1 加密方式确认通过分析定位到的JS代码确定签名采用的是HMAC-MD5加密而非普通MD5加密用到固定密钥签名字符串为接口路径请求参数拼接后的字符串。4.2 逻辑补全对照原生JS逻辑剔除压缩混淆的代码还原清晰的拼接、加密流程拼接基础接口路径/audiostream/redirect/节目ID/音频ID拼接请求参数生成query字符串将完整路径参数字符串作为待加密内容通过HMAC-MD5算法配合固定密钥生成签名将签名拼接到链接末尾得到最终可播放地址五、完整代码实现本次实现分为两部分Python爬虫负责抓取节目ID、音频IDJS文件负责生成加密签名两者联动实现自动化获取音频链接。5.1 Python爬虫代码FM.py该文件负责请求页面抓取页面内的专辑ID和所有音频ID随后调用JS文件生成签名链接打印完整可播放地址。importrequestsimportreimportjsonimportsubprocessimportsys# 请求头与Cookie配置cookies{HWWAFSESID:9101282dec5b2ddcab,HWWAFSESTIME:1774584394048,Hm_lvt_bbe853b61e20780bcb59a7ea2d051559:1774584397,HMACCOUNT:7BD2AC601EA0EC1B,Hm_lpvt_bbe853b61e20780bcb59a7ea2d051559:1774585448,}headers{Accept:text/html,application/xhtmlxml,application/xml;q0.9,image/webp,image/apng,*/*;q0.8,User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36,}# 请求目标音频专辑页面responserequests.get(https://www.xxx.cn/channels/322795/,cookiescookies,headersheaders)htmlresponse.text# 截取页面内的JSON数据获取音频列表resultre.search(rwindow.__initStores(\{.*\})\s*\/script,html,re.S)ifresult:datajson.loads(result.group(1))ciddata[AlbumStore][cid]plistdata[AlbumStore][plist]# 遍历所有音频调用JS生成签名链接forindex,iteminenumerate(plist):audio_idstr(item[id])titleitem[title]try:# 调用FM.js传递参数生成播放链接resultsubprocess.run([node,FM.js,cid,audio_id],capture_outputTrue,textTrue,encodingutf-8)final_urlresult.stdout.strip()print(f[{index1}]{title})print(f音频ID{audio_id})print(f播放地址{final_url})print(-*60)exceptExceptionase:print(f[{index1}]{title}| 链接生成失败)else:print(未匹配到页面数据)5.2 JS签名生成代码FM.js该文件负责接收Python传递的参数拼接链接并生成HMAC-MD5签名返回完整可播放的音频链接。constcryptorequire(crypto);// 接收Python传递的频道ID、音频IDconstcidprocess.argv[2];constaudioIdprocess.argv[3];// 固定参数配置constaccess_token;constqingting_id;constdomainhttps://audio.xxx.cn;constSECRET_KEY7l8CZ)SgZgM_bkrw;// 拼接音频链接并生成签名functiongetAudioUrl(e,t){if(et){constparams{access_token:access_token,device_id:MOBILESITE,qingting_id:qingting_id,t:Date.now()};// 拼接接口路径与参数lets/audiostream/redirect/${e}/${t};constqueryStrnewURLSearchParams(params).toString();if(queryStr)s?queryStr;// HMAC-MD5加密生成签名constsigncrypto.createHmac(md5,SECRET_KEY).update(s).digest(hex);returndomainssignsign;}return;}// 输出结果给Pythonconsole.log(getAudioUrl(cid,audioId));六、运行说明确保电脑已安装Node.js和Python环境将FM.py和FM.js放在同一文件夹下直接运行FM.py文件即可自动抓取音频列表并生成所有可播放链接本文仅用于编程技术学习与逆向分析交流所涉及代码仅用于学习测试严禁用于商业盈利、大规模爬取数据、侵权传播等违规违法用途由此产生的一切法律责任自行承担。如果觉得教程对你有帮助关注我持续获取硬核的编程逆向、爬虫实战技术教程后续还会更新更多实战案例和技术干货喔