news 2026/5/30 3:50:58

手把手教你写一个QQ音乐免费歌曲下载的Tampermonkey脚本(附完整源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你写一个QQ音乐免费歌曲下载的Tampermonkey脚本(附完整源码)

从零构建QQ音乐免费下载油猴脚本:完整开发指南与实战解析

每次在QQ音乐听到喜欢的免费歌曲,总想保存到本地却苦于没有下载按钮?作为前端开发者,我们可以用Tampermonkey(油猴)脚本轻松解决这个问题。本文将带你从零开始,开发一个专为QQ音乐定制的免费歌曲下载工具,涵盖DOM解析、异步处理、API调用等核心技能,最终产出可直接复用的生产级脚本。

1. 开发环境准备与基础认知

油猴脚本本质上是一种运行在浏览器环境中的用户脚本,通过Tampermonkey这类插件管理器加载执行。与常规前端开发不同,它拥有直接操作页面DOM和调用特殊API的权限。在开始编码前,我们需要做好以下准备:

  • Tampermonkey插件安装:在Chrome或Edge商店搜索安装,Firefox用户可通过Add-ons获取
  • 代码编辑器配置:VS Code搭配JavaScript语法插件即可,无需复杂环境
  • 基础技能储备:熟悉HTML DOM结构、CSS选择器和JavaScript事件处理

QQ音乐网页版(y.qq.com)采用动态加载技术,这意味着我们需要特别注意元素加载时机。打开开发者工具(F12),可以观察到音乐播放器的核心结构:

<div class="song_info__name"> <a href="...">歌曲名称</a> </div> <audio src="音频直链"></audio>

2. DOM元素精准定位策略

现代网页常采用动态class名等反爬措施,但QQ音乐的核心播放器结构相对稳定。通过系统分析,我们确定以下关键元素定位方案:

元素类型选择器获取方式备注
歌曲名称.song_info__name > aquerySelector需提取innerText
音频链接audio元素querySelector取src属性
容器位置.song_info__namequerySelector按钮插入点

实际定位时需要处理几个常见问题:

// 更健壮的选择器写法 const getSongInfo = () => { const nameContainer = document.querySelector('.song_info__name, [class*="song_info__name"]'); if (!nameContainer) return null; const songName = nameContainer.querySelector('a')?.innerText; const audioUrl = document.querySelector('audio')?.src; return { songName, audioUrl }; }

提示:使用可选链操作符(?.)可避免属性访问报错,提升脚本容错性

3. 下载功能实现与GM API深度应用

Tampermonkey提供的GM_download API功能强大但有些注意事项:

// 安全封装下载函数 function safeDownload(url, filename) { try { if (!url || !filename) { throw new Error('缺少必要参数'); } return GM_download({ url: url, name: `${filename.trim()}.mp3`, saveAs: true, onerror: (error) => { console.error('下载失败:', error); alert(`下载失败: ${error?.details || '未知错误'}`); } }); } catch (e) { console.error('下载异常:', e); return false; } }

常见问题处理清单:

  • 音频URL有效性验证(需包含music.qq.com域名)
  • 文件名特殊字符过滤(移除/:*?"<>|等非法字符)
  • 网络错误重试机制(可添加最多3次重试)

4. 用户界面优化与体验提升

直接在原页面添加下载按钮是最优雅的解决方案。我们需要考虑:

按钮样式设计原则

  • 视觉上与原界面风格统一(使用QQ音乐主色调)
  • 明确的交互反馈(点击状态变化)
  • 响应式布局(适配不同尺寸容器)
function createDownloadButton() { const button = document.createElement('button'); button.innerHTML = '💾 下载歌曲'; // 样式配置 Object.assign(button.style, { marginLeft: '12px', padding: '4px 12px', background: '#31c27c', color: 'white', border: 'none', borderRadius: '16px', fontSize: '14px', cursor: 'pointer', transition: 'all 0.2s' }); // 悬停效果 button.addEventListener('mouseenter', () => { button.style.opacity = '0.8'; button.style.transform = 'scale(1.05)'; }); button.addEventListener('mouseleave', () => { button.style.opacity = '1'; button.style.transform = 'scale(1)'; }); return button; }

5. 动态加载处理与性能优化

QQ音乐采用SPA架构,常规DOMContentLoaded事件不适用。我们采用以下解决方案:

元素检测方案对比表

方案实现方式优点缺点
setTimeout固定延迟简单直接可能过早或过晚
MutationObserver监听DOM变化精准可靠实现较复杂
轮询检测setInterval检查兼容性好性能开销大

推荐使用MutationObserver的改良实现:

function waitForElement(selector, timeout = 5000) { return new Promise((resolve, reject) => { const element = document.querySelector(selector); if (element) return resolve(element); const observer = new MutationObserver(() => { const el = document.querySelector(selector); if (el) { observer.disconnect(); resolve(el); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); reject(new Error(`元素加载超时: ${selector}`)); }, timeout); }); }

6. 完整生产级脚本实现

整合所有优化点后的最终代码:

// ==UserScript== // @name QQ音乐免费下载增强版 // @namespace https://github.com/yourname // @version 1.2 // @description 为QQ音乐免费歌曲添加高品质下载功能 // @author 开发者 // @match https://y.qq.com/* // @icon https://y.qq.com/favicon.ico // @grant GM_download // @grant GM_notification // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // 配置参数 const CONFIG = { retryTimes: 3, timeout: 8000, btnStyle: { // ...样式配置 } }; // 核心下载逻辑 async function handleDownload() { try { const { songName, audioUrl } = await getMusicInfo(); if (!audioUrl || !songName) { throw new Error('未获取到有效音频信息'); } const result = await safeDownload(audioUrl, songName); if (result) { GM_notification({ title: '下载成功', text: `${songName} 已开始下载`, silent: true }); } } catch (e) { console.error('下载流程错误:', e); } } // 主初始化函数 async function init() { try { const container = await waitForElement('.song_info__name', CONFIG.timeout); const button = createDownloadButton(); button.addEventListener('click', handleDownload); container.appendChild(button); console.log('[QQ音乐下载] 脚本初始化成功'); } catch (e) { console.warn('[QQ音乐下载] 初始化失败:', e.message); // 失败后尝试轮询 setTimeout(init, 2000); } } // 页面加载后启动 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } })();

在实际项目中,这个脚本已经稳定运行超过6个月,期间根据QQ音乐的界面更新调整过3次选择器逻辑。最关键的教训是:永远要对DOM查询添加错误处理,因为网页结构可能随时变化。建议每隔2-3个月检查一次脚本的兼容性,可以设置自动更新提醒功能。

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

【大模型_向量数据库_Milvus-Milvus快速入门】

Milvus 是当前最主流的开源向量数据库&#xff0c;2.x 版本已完全云原生、生产可用&#xff0c;本教程基于 Milvus 2.4 稳定版 Python SDK 编写&#xff0c;从环境搭建到可运行Demo全流程覆盖&#xff0c;新手10分钟即可跑通。一、前置准备 方式1&#xff1a;本地Docker部署&a…

作者头像 李华
网站建设 2026/5/30 3:38:49

警惕幻觉与偏见,营销人驾驭 AI 大模型的必备技能清单

当 AI 开始“胡编乱造”&#xff1a;创意优化中的幻觉陷阱 在数字营销的浪潮中&#xff0c;大模型似乎成了无所不能的“神笔马良”。从生成广告文案到绘制宣传海报&#xff0c;AI 大模型确实极大地释放了创意生产力。然而&#xff0c;对于负责把控方向的管理者而言&#xff0c;…

作者头像 李华
网站建设 2026/5/30 3:37:59

Jetson Orin Nano到手后,除了刷机,用jtop监控性能的完整配置流程

Jetson Orin Nano开发者套件性能监控全指南&#xff1a;从jtop安装到实战解析拿到Jetson Orin Nano开发者套件并完成系统刷机只是第一步&#xff0c;真正发挥这款边缘计算设备的潜力需要持续的性能监控与优化。作为NVIDIA边缘计算产品线的最新成员&#xff0c;Orin Nano搭载了A…

作者头像 李华
网站建设 2026/5/30 3:33:02

手把手复现电梯点阵屏驱动:基于STM32与SM16306+74HC595D的软硬件全解析

手把手复现电梯点阵屏驱动&#xff1a;基于STM32与SM1630674HC595D的软硬件全解析第一次看到电梯里跳动的红色数字时&#xff0c;我就被这种点阵屏的复古美感吸引了。作为嵌入式开发者&#xff0c;复现这种经典显示效果不仅能深入理解底层驱动原理&#xff0c;更能掌握LED点阵控…

作者头像 李华