Python爬虫:获取某平台数据的下载链接 - 指南

news/2025/10/23 16:37:45/文章来源:https://www.cnblogs.com/wzzkaifa/p/19161028

searchid的生成参考代码如下:

function a(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = [], i = n.length, o = a.length, c = 0, s = i + o - 1; c <= s; c++)
r[c] = 0;
for (var l = 0; l < o; l++)
for (var u = 0; u < i; u++)
r[u + l] += parseInt(n[u], 10) * parseInt(a[l], 10),
r[u + 1 + l] += Math.floor(r[u + l] / 10),
r[u + l] = r[u + l] % 10;
return r.reverse(),
0 == r[0] && r.shift(),
r.join("")
}
function r(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = n.length, i = a.length, o = 0, c = 0, s = 0, l = 0, u = 0, m = Math.max(r, i); u < m; u++)
c = u < r ? parseInt(n[u], 10) : 0,
s = u < i ? parseInt(a[u], 10) : 0,
l = Math.round(c) + Math.round(s) + o,
n[u] = "".concat(l % 10),
o = l >= 10 ? 1 : 0;
return 1 == o && n.push("1"),
n.reverse().join("")
}
function getSearchId(){
const e = 3;
var t = a(e, "18014398509481984")
, n = a(Math.round(Math.random() * parseInt("4194304", 10)), "4294967296")
, i = new Date
, o = 1e3 * (3600 * i.getHours() + 60 * i.getMinutes() + i.getSeconds()) + i.getMilliseconds();
return r(r(t, n), o)
}
console.log(getSearchId())

Python爬虫代码如下:

import requests
import numpy as np
import subprocess
import json
import execjs
import time
keyword = input("输入关键词:")
cookies = ''  # 这部分为你自己的cookie信息
with open(file='encode_random.js', mode='r', encoding='utf-8') as f:
js_str1 = f.read()
with open(file='encode_sign.js', mode='r', encoding='utf-8') as f:
js_str2 = f.read()
with open(file='encode_data.js', mode='r', encoding='utf-8') as f:
js_str3 = f.read()
with open(file='person.txt', mode='r', encoding='utf-8') as f:
QQ_str = f.read()
ctx = execjs.compile(js_str1)
searchid = ctx.call('getSearchId')
tk2 = ctx.call('get_tk', cookies)
obj = {
"comm": {
"cv": 4747474,
"ct": 24,
"format": "json",
"inCharset": "utf-8",
"outCharset": "utf-8",
"notice": 0,
"platform": "yqq.json",
"needNewCode": 1,
"uin": QQ_str,
"g_tk_new_20200303": tk2,
"g_tk": tk2
},
"req_1": {
"method": "DoSearchForQQMusicDesktop",
"module": "music.search.SearchCgiService",
"param": {
"remoteplace": "txt.yqq.song",
"searchid": searchid,
"search_type": 0,
"query": keyword,
"page_num": 1,
"num_per_page": 10
}
}
}
ctx2 = execjs.compile(js_str2)
sign = ctx2.call('main', obj)
time2 = int(time.time() * 1000)
params = {
'_': time2,
'encoding': 'ag-1',
'sign': sign
}
ctx3 = execjs.compile(js_str3)
url = 'https://u6.y.qq.com/cgi-bin/musics.fcg'
with open(file='2.js', mode='w', encoding='utf-8') as f:
f.write(js_str3 + f'\nmain1({obj})')
res = subprocess.run(['node', '2.js'], capture_output=True)
# 这里的js代码进行了异步操作,无法直接用execjs模块运行
data = res.stdout.decode('utf-8').split('\n')[0]
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
'cookie': cookies
}
rsp = requests.post(url=url, headers=headers, data=data, params=params)
content = rsp.content
byte_arr = np.frombuffer(content, dtype=np.uint8)
arr = [int(e) for e in byte_arr]
with open(file='decode.js', mode='r', encoding='utf-8') as f:
js_str = f.read()
# 这里解密操作arr数组因为涉及js与python的数据不兼容的问题,使用subprocess执行js代码
with open(file='1.js', mode='w', encoding='utf-8') as f:
f.write(js_str + f'\nconsole.log(main({arr}))')
res = subprocess.run(['node', '1.js'], capture_output=True)
res_str = res.stdout.decode('utf-8').split('\n')[0]
with open(file='res.json', mode='w', encoding='utf-8') as f:
f.write(res_str)
map = json.loads(res_str)
songs = map['req_1']['data']['body']['song']['list']
for i, song in enumerate(songs):
id, mid = song['id'], song['mid']
singer = ','.join([s['name'] for s in song['singer']])
title = song['title']
print(i + 1, title, singer, id, mid)
index = int(input('输入想下载的歌曲id:'))
song_info = songs[index - 1]
song_id = song_info['id']
song_mid = song_info['mid']
album_mid = song_info['album']['mid']
d2 = song_info['vs'][0]
d3 = song_info['file']['media_mid']
pay_play = song_info['pay']['pay_play']
guid_js = '''
function main(){
let a = (new Date).getUTCMilliseconds();
return String(Math.round(2147483647 * Math.random()) * a % 1e10);
}
'''
guid = execjs.compile(guid_js).call('main')
obj2 = {"comm": {"cv": 4747474, "ct": 24, "format": "json", "inCharset": "utf-8", "outCharset": "utf-8", "notice": 0,
"platform": "yqq.json", "needNewCode": 1, "uin": QQ_str, "g_tk_new_20200303": tk2,
"g_tk": tk2},
"req_1": {"module": "music.musicasset.SongFavRead", "method": "IsSongFanByMid",
"param": {"v_songMid": [song_mid]}},
"req_2": {"module": "music.musichallSong.PlayLyricInfo", "method": "GetPlayLyricInfo",
"param": {"songMID": song_mid, "songID": song_id}},
"req_3": {"method": "GetCommentCount", "module": "music.globalComment.GlobalCommentRead",
"param": {"request_list": [{"biz_type": 1, "biz_id": str(song_id), "biz_sub_type": 0}]}},
"req_4": {"module": "music.musichallAlbum.AlbumInfoServer", "method": "GetAlbumDetail",
"param": {"albumMid": album_mid}},
"req_5": {"module": "music.vkey.GetEVkey", "method": "GetUrl",
"param": {"guid": guid, "songmid": [song_mid], "songtype": [0], "uin": QQ_str,
"loginflag": 1, "platform": "20", "xcdn": 1}}}
if pay_play == 1:
obj2['req_5']['param']['filename'] = [f"RS02{d2 or d3}.mp3"]
sign2 = ctx2.call('main', obj2)
params = {
'_': int(time.time() * 1000),
'encoding': 'ag-1',
'sign': sign2
}
with open(file='3.js', mode='w', encoding='utf-8') as f:
f.write(js_str3 + f'\nmain1({obj2})')
res = subprocess.run(['node', '3.js'], capture_output=True)
# 这里的js代码进行了异步操作,无法直接用execjs模块运行
data = res.stdout.decode('utf-8').split('\n')[0]
rsp2 = requests.post(url=url, headers=headers, data=data, params=params)
content = rsp2.content
byte_arr = np.frombuffer(content, dtype=np.uint8)
arr = [int(e) for e in byte_arr]
with open(file='decode.js', mode='r', encoding='utf-8') as f:
js_str = f.read()
# 这里解密操作arr数组因为涉及js与python的数据不兼容的问题,使用subprocess执行js代码
with open(file='4.js', mode='w', encoding='utf-8') as f:
f.write(js_str + f'\nconsole.log(main({arr}))')
res = subprocess.run(['node', '4.js'], capture_output=True)
res_str = res.stdout.decode('utf-8').split('\n')[0]
with open(file='6.json', mode='w', encoding='utf-8') as f:
f.write(res_str)
map = json.loads(res_str)
download_url = map['req_5']['data']['midurlinfo'][0]['xcdnurl']
download_url2 = 'https://ws6.stream.qqmusic.qq.com/' + map['req_5']['data']['midurlinfo'][0]['purl']
if pay_play == 1:
print("当前歌曲需要vip,试听下载链接为:",download_url2)
else:
print('下载链接:', download_url)

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

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

相关文章

厨房电子秤芯片方案:SIC8632

本文主要描述基于SIC8632芯片研发的电容式厨房电子秤方案。一、MCU芯片的选择原则高精度:厨房秤需要能够精确测量食材的重量,因此MCU芯片应具备高精度模数转换(ADC)功能,以实现对传感器输出信号的准确采样和转换。…

《借力JBoltAI框架,Java技术开发公司开启高效开发新范式》

在当今竞争激烈的软件开发领域,Java技术凭借其跨平台、面向对象、稳定性强等诸多优势,成为了众多企业开发各类应用的首选。对于专注于Java技术开发的公司而言,不断提升开发效率、优化项目质量、降低开发成本,是在市…

Wireshark抓包教程:JSON和HTTPS抓取

本文详细讲解Wireshark抓包工具的使用方法,涵盖JSON网址抓取、HTTPS流量捕获、数据包过滤技巧和TCP握手挥手分析。wireshark能抓取JSON网址吗 wireshark可以抓https吗 Wireshark 是一个 网络封包 分析软件。帮你撷取网…

贡献法算法思维

贡献法算法思维 Prompt: 贡献法算法思维是怎样的 Response: 非常好的问题👏!你问的这个「贡献法」,是算法竞赛中非常常见、非常重要的一种思维方式,尤其在处理计数问题、期望问题、子区间问题、树上路径问题时常常…

白鲸开源数据基建平台荣登“创客北京 2025”企业组TOP150,共同助 Agentic AI 行业变革

近日,第十届“创客中国”北京市中小企业创新创业大赛暨“创客北京2025”创新创业大赛结果揭晓,北京白鲸开源科技有限公司凭借“白鲸开源-Agentic AI 时代下的数据基础设施平台”,荣登企业组 TOP150,并获得大赛组委…

ORACLE检查并创建表空间和表分区

为确保系统在高并发、大数据量环境下的稳定高效运行,要求建立完善的表空间与表分区管理机制,具体包括:定期检查表空间使用率,及时发现并处理空间不足风险;建立分区自动创建与维护流程,防止因分区缺失导致的数据插…

让cherry studio访问使用Docket Desktop中的Docker Model Runner运行的模型

添加自定义提供商,类型选OpenAI。API密钥随意(可以填none) API地址填http://localhost:12434/engines/llama.cpp模型 点击管理选择列出来的模型即可注意:模型名称要按下图中输入docker model ps命令出来的名称填写…

禁用内核模块,是否需要执行脚本 $ sudo update-initramfs -u $ sudo update-grub ? - 详解

禁用内核模块,是否需要执行脚本 $ sudo update-initramfs -u $ sudo update-grub ? - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

2025 年东莞钢结构厂房施工公司最新推荐榜:聚焦企业专利技术、品质管控及知名客户合作案例的权威解析

在工业建筑领域,钢结构厂房以其施工效率高、结构稳定性强等优势,成为众多企业的首选。随着市场需求增长,专业施工公司的综合实力成为用户关注焦点。本文基于企业资质、项目经验、技术团队规模及服务质量等维度,对东…

高性能AI股票预测分析报告 - 2025年10月23日

高性能AI股票预测分析报告 - 2025年10月23日body { font-family: "Microsoft YaHei", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: rgba(51, 51, 51, 1); max-wi…

2025 年电子万能试验机生产厂家最新推荐榜:聚焦企业专利技术、品质管控及知名客户合作案例的权威解析

电子万能试验机作为材料力学性能测试的核心设备,广泛应用于工业制造、科研教育及质量控制领域。随着制造业升级和技术迭代,市场对试验机的精度、稳定性和智能化提出了更高要求。本报告基于行业数据、技术参数及用户反…

Spring AI Alibaba Admin 正式开源!!

大家好,我是R哥。 最近,阿里巴巴又开源了一款新项目——Spring AI Alibaba Admin,这是一款面向生产级场景的一体化 AI Agent 应用研发治理平台,解决了企业级 AI Agent 在开发与运维过程中面临的工程化难题。 项目地…

snack4-jsonpath v4.0.2 发布

Snack-Jsonpath 支持 JSON DOM 构建、编解码、JsonPath 查询和 JsonSchema 验证。核心特性包括高性能 JsonPath 查询(兼容 IETF 和 jayway 标准)、JsonSchema 校验、Json5 部分特性支持,以及优先使用无参构造的安全…

SMARTFORMS去掉数值后面的小数点

DATA: lv_value TYPE string VALUE 12.012.CONDENSE lv_value NO-GAPS. SHIFT lv_value RIGHT DELETING TRAILING 0. SHIFT lv_value RIGHT DELETING TRAILING ..WRITE lv_value.

089_尚硅谷_switch的课堂练习

089_尚硅谷_switch的课堂练习1.练习1.使用switch 把小写类型的 char型转为大写,只转换a, b, c, d, e其它的输出 `other` 2.对学生成绩大于60分的,输出`合格`。低于60分的,输出`不合格`。(注: 输入的成绩不能大于10…

SQL SERVER死锁查询,死锁分析,解锁,查询占用

From: https://www.cnblogs.com/K-R-/p/18431639 简单点的处理方法: 1、查询死锁的表select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resourc…

自定义组件中监听properties里面的属性的方法里面去取另外的properties里面的属性拿不到值的问题

自定义组件中监听properties里面的属性的方法里面去取另外的properties里面的属性拿不到值的问题1 properties这里有两个属性 options和modelValue,对modelValue进行监听父组件两个属性都传了值properties: {options:…

数字征程,逐级而上;生态协同,智绘新篇—— 艾拓琪威灏 与 哲讯顺维 数字化战略合作签署暨CRMMES项目启动会隆重举行

在时代的巨轮驶向数字经济的深水区,企业的进化不再是零敲碎打的工具升级,而是一场关乎全局、贯穿价值链的战略重塑。回首过往,每一步坚实的足迹都预示着今天的必然。从2022年智能会议室的初步尝试,到2023年OA协同办…

嵌入式主板全景解析:从选型到趋势,读懂工业智能的核心载体

在智能制造车间的机械臂控制系统中,在偏远地区的电力监控终端里,在医院的便携式监护仪内部,都藏着同一个核心硬件—— 嵌入式主板。作为连接硬件组件与软件系统的 "神经中枢",它不仅决定着设备的运行效率…

2025 年唐山油漆生产厂家最新推荐榜单:精选优质企业,解析专业品牌选购指南唐山油漆批发/唐山油漆生产公司推荐

引言 随着环保政策收紧与产业升级加速,唐山油漆市场呈现 “新旧品牌迭代、技术加速升级” 的态势,但同时也存在信息不对称、产品质量悬殊等问题 —— 部分企业仍沿用传统工艺,VOC 排放超标,而新兴品牌虽技术先进却…