Python爬虫实战:网易云音乐榜单歌曲批量下载器
·
项目概述
本文将介绍如何使用Python开发一个网易云音乐榜单歌曲批量下载器。这个工具可以帮助你轻松下载网易云音乐任意榜单中的所有歌曲,只需输入榜单名称和ID即可。项目使用requests库进行网络请求,re库进行正则表达式匹配,实现了简单高效的音乐下载功能。
技术栈
- Python 3.x
- requests: 用于发送HTTP请求,获取网页内容和下载音乐文件
- re: 正则表达式,用于解析网页内容,提取歌曲信息
- os: 用于文件和目录操作
- tqdm: 用于显示下载进度条,提升用户体验
项目结构
import requests
import re
import os
from tqdm import tqdm
# 请求头配置
headers = {
# 请求头信息
}
def createFolder(name):
"""创建对应的文件夹"""
def get_html(rankId):
"""获取网页的内容"""
def get_music(htmlContent):
"""获取歌曲信息"""
def downloadMusic(name, InfoList):
"""下载歌曲"""
if __name__ == '__main__':
# 主程序入口
详细实现
1. 请求头配置
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'cookie': '_iuqxldmzr_=32; _ntes_nnid=5fe3228939599e5837938ad61adb3b47,1763302635945; _ntes_nuid=5fe3228939599e5837938ad61adb3b47; NMTID=00O-LksnKg26W4HyE87rnxuiV7Dky4AAAGajQb3Mw; WEVNSM=1.0.0; WNMCID=ounhws.1763302636890.01.0; WM_TID=gzL05QFZdMVEEQQUERPTzdGzVHtXCmU%2B; sDeviceId=YD-SrNUhGX1pEZFRlQRURLD3IHyQWtSD5S7; ntes_utid=tid._.QKG8PdhVL3BFV0AAVQfGyZCjRD5SX8X9._.0; __snaker__id=USbawQMECvM3w1un; ntes_kaola_ad=1; __remember_me=true; MUSIC_U=00253093384AAA22E1341DE736D1774F2CD0BDE81EA787B6A25C248181E86B6472E3B5FF91CDBDB5F617E52F7D8CD9C775E245C968CBBDA7175C9538AE2396AD12591839F88E8F03DB8D62F6B9C74BC9E50BC768F7D4E52AE1164D9697A2872D5D56C30A324D5623F098041668CC33A46FC020CAF21430CB58BA0AEAB0AB1C50805933B510B607F9C46F6407E05EEC65D1367ABD73AC498229FBABC6471E664E2A6A139900E943824236EDA120880F6DEE539DA3B9CBB3056873CB500B1240C39E0B0D833C84516FA6717775E03D18F2CF949D548409688DD59232B69A3F43AFA7784790562078E6261A57DFD906339B9402FC72A04A79D5242CAB47DBE963FB386EE1D730CBA177F113E77FD1615B8AD4ED08151B5DA923D9907121A1B6ABA223CDC591C516FFFF1C557EEE821890500DB0B12B6135CDD31A1125546A27233F6AB36EAFF41AEADB3E6399394C2FB3E933FCBB7BDDF75203C436F644D6BF6CE4ED5DBC4226133B71CB4B77855BBBA5C9E3C7B46931594CE3995508F8BE0A52B32F65FE73946A0C17EF069F6DBA1397E9F803BEEEB62F47ED95EE69DFF31963D9EF; vinfo_n_f_l_n3=7c9909ea4d9edf3c.1.0.1766121512724.0.1766121519248; _ntes_origin_from=bing; __csrf=5d21084669e73ce3cfe23f7f9a4fd530; WM_NI=VGerjPqhJ9673ErUbGBzhhHK5Enh8zdTArIpaDulz4qIKaio2yM2mTWLZ2d%2FtBNEZkRrol0QQGqApoCYUmSxTeNGM9PtPY8H9QCcnImOtQaEFLGq9Qjoot5ilt9v0WvwOTU%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6ee8ece7391b28b85ca4ff89a8ab6c85f938e8e87c239b3bcffb0ed5382eb9b86c72af0fea7c3b92a9699ab93e95cb3b886dab53df19bbeb6e14d82a6a889cb41f79ba289bb72a88c8f93cc7ca39cbb8df940b3978582ec65f2a783d3f060959496d3e725b89e82a6d96192aea18db35b9399bfa2f36581879b8ed27498bb82a8d03394aca0babb44fb8f8d84ed43af91bcb2e44f86948992bc5baab1a195b863b0acf797b35db6a981b5d837e2a3; gdxidpyhxdE=PYix989AZJ9SC%2BPUycA7n6QsVxlSGMTlRe0w%2B1mZ2tLH0tIVaXQyLiTy4pjG5j7kHw0hvBujvbCdatWHGpyJvho81%2FE2Wtv9ITYNbaifo%2Fj30Z1wQsuEEDxpSJXNuxbvr6qSevd1o40%5CjcULiA%5CfaBORoKg6Dq7ZDaJxRZlkEbEowPKt%3A1768797806468; JSESSIONID-WYYY=hG9oZpf72h%2Fsx1OAKx3KPgKTHpXucGT6SwIrME7uIPr9%2FEv%5CbfUJ9%2B7PGwJ5U6%5CYJcG5Hd9uO%2FQKu%5CRXCfsCyS75Jf3VU8%2Fj5CE%5C%2BmarKj9iiW%2BcDJ7zuF58FSkfiN3zo4o8%2BSbDnfb0BS%2FY2986m%2F7tNMhnINSylSrzFZWagnYYPQp4%3A1768799532469',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0'
}
配置了完整的请求头信息,包括accept、cookie和user-agent,这有助于模拟浏览器行为,避免被网易云音乐的反爬机制识别。
2. 创建文件夹函数
def createFolder(name):
"""
创建对应的文件夹
:param name: 文件名
:return:
"""
if not os.path.exists(name):
os.mkdir(name)
这个函数用于创建存储下载音乐的文件夹。它会检查指定名称的文件夹是否已存在,如果不存在则创建新文件夹。
3. 获取网页内容函数
def get_html(rankId):
"""
获取网页的内容
:param rankId: 榜单id
:return: 返回网页内容
"""
# 榜单网址
url = f'https://music.163.com/discover/toplist?id={rankId}'
# 向网页发起请求
response = requests.get(url, headers=headers)
# 返回网页内容
return response.text
这个函数接收一个榜单ID作为参数,构建完整的榜单页面URL,然后发送HTTP GET请求获取页面内容。
4. 提取歌曲信息函数
def get_music(htmlContent):
"""
获取歌曲
:param htmlContent: 网页内容
:return: 返回获取的id和标题列表
"""
# 获取歌曲的id和标题
musicInfo = re.findall(r'<a href="/song\?id=(\d+)">(.*?)</a>', htmlContent)
return musicInfo
这个函数使用正则表达式从网页内容中提取歌曲ID和标题。它查找所有匹配<a href="/song?id=歌曲ID">歌曲标题</a>模式的内容,并返回一个包含(歌曲ID, 歌曲标题)元组的列表。
5. 下载音乐函数
def downloadMusic(name, InfoList):
"""
下载歌曲
:param name: 文件名
:param InfoList: 歌曲的id和标题列表
:return:
"""
for music_id, music_title in tqdm(InfoList):
# 歌曲的url
music_url = f'https://music.163.com/song/media/outer/url?id={music_id}.mp3'
music = requests.get(music_url, headers=headers).content
# 将获取的歌曲存储在文件夹中
with open(name + '\\' + music_title + '.mp3', 'wb') as f:
f.write(music)
这个函数负责下载歌曲:
- 使用
tqdm库显示下载进度条 - 遍历歌曲信息列表,对每首歌曲:
- 构建音乐文件的URL
- 发送请求获取音乐文件内容
- 将音乐文件保存到指定文件夹中
6. 主程序
if __name__ == '__main__':
filename = input('请输入榜单名称: ')
createFolder(filename)
rank_id = input('请输入榜单id: ')
html = get_html(rank_id)
# 歌曲信息列表
musicInfoList = get_music(html)
# 下载音乐
downloadMusic(filename, musicInfoList)
主程序流程:
- 提示用户输入榜单名称
- 创建对应名称的文件夹
- 提示用户输入榜单ID
- 获取榜单页面内容
- 提取歌曲信息
- 下载所有歌曲到创建的文件夹中
完整代码
import requests
import re
import os
from tqdm import tqdm
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'cookie': '_iuqxldmzr_=32; _ntes_nnid=5fe3228939599e5837938ad61adb3b47,1763302635945; _ntes_nuid=5fe3228939599e5837938ad61adb3b47; NMTID=00O-LksnKg26W4HyE87rnxuiV7Dky4AAAGajQb3Mw; WEVNSM=1.0.0; WNMCID=ounhws.1763302636890.01.0; WM_TID=gzL05QFZdMVEEQQUERPTzdGzVHtXCmU%2B; sDeviceId=YD-SrNUhGX1pEZFRlQRURLD3IHyQWtSD5S7; ntes_utid=tid._.QKG8PdhVL3BFV0AAVQfGyZCjRD5SX8X9._.0; __snaker__id=USbawQMECvM3w1un; ntes_kaola_ad=1; __remember_me=true; MUSIC_U=00253093384AAA22E1341DE736D1774F2CD0BDE81EA787B6A25C248181E86B6472E3B5FF91CDBDB5F617E52F7D8CD9C775E245C968CBBDA7175C9538AE2396AD12591839F88E8F03DB8D62F6B9C74BC9E50BC768F7D4E52AE1164D9697A2872D5D56C30A324D5623F098041668CC33A46FC020CAF21430CB58BA0AEAB0AB1C50805933B510B607F9C46F6407E05EEC65D1367ABD73AC498229FBABC6471E664E2A6A139900E943824236EDA120880F6DEE539DA3B9CBB3056873CB500B1240C39E0B0D833C84516FA6717775E03D18F2CF949D548409688DD59232B69A3F43AFA7784790562078E6261A57DFD906339B9402FC72A04A79D5242CAB47DBE963FB386EE1D730CBA177F113E77FD1615B8AD4ED08151B5DA923D9907121A1B6ABA223CDC591C516FFFF1C557EEE821890500DB0B12B6135CDD31A1125546A27233F6AB36EAFF41AEADB3E6399394C2FB3E933FCBB7BDDF75203C436F644D6BF6CE4ED5DBC4226133B71CB4B77855BBBA5C9E3C7B46931594CE3995508F8BE0A52B32F65FE73946A0C17EF069F6DBA1397E9F803BEEEB62F47ED95EE69DFF31963D9EF; vinfo_n_f_l_n3=7c9909ea4d9edf3c.1.0.1766121512724.0.1766121519248; _ntes_origin_from=bing; __csrf=5d21084669e73ce3cfe23f7f9a4fd530; WM_NI=VGerjPqhJ9673ErUbGBzhhHK5Enh8zdTArIpaDulz4qIKaio2yM2mTWLZ2d%2FtBNEZkRrol0QQGqApoCYUmSxTeNGM9PtPY8H9QCcnImOtQaEFLGq9Qjoot5ilt9v0WvwOTU%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6ee8ece7391b28b85ca4ff89a8ab6c85f938e8e87c239b3bcffb0ed5382eb9b86c72af0fea7c3b92a9699ab93e95cb3b886dab53df19bbeb6e14d82a6a889cb41f79ba289bb72a88c8f93cc7ca39cbb8df940b3978582ec65f2a783d3f060959496d3e725b89e82a6d96192aea18db35b9399bfa2f36581879b8ed27498bb82a8d03394aca0babb44fb8f8d84ed43af91bcb2e44f86948992bc5baab1a195b863b0acf797b35db6a981b5d837e2a3; gdxidpyhxdE=PYix989AZJ9SC%2BPUycA7n6QsVxlSGMTlRe0w%2B1mZ2tLH0tIVaXQyLiTy4pjG5j7kHw0hvBujvbCdatWHGpyJvho81%2FE2Wtv9ITYNbaifo%2Fj30Z1wQsuEEDxpSJXNuxbvr6qSevd1o40%5CjcULiA%5CfaBORoKg6Dq7ZDaJxRZlkEbEowPKt%3A1768797806468; JSESSIONID-WYYY=hG9oZpf72h%2Fsx1OAKx3KPgKTHpXucGT6SwIrME7uIPr9%2FEv%5CbfUJ9%2B7PGwJ5U6%5CYJcG5Hd9uO%2FQKu%5CRXCfsCyS75Jf3VU8%2Fj5CE%5C%2BmarKj9iiW%2BcDJ7zuF58FSkfiN3zo4o8%2BSbDnfb0BS%2FY2986m%2F7tNMhnINSylSrzFZWagnYYPQp4%3A1768799532469',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0'
}
def createFolder(name):
"""
创建对应的文件夹
:param name: 文件名
:return:
"""
if not os.path.exists(name):
os.mkdir(name)
def get_html(rankId):
"""
获取网页的内容
:param rankId: 榜单id
:return: 返回网页内容
"""
# 榜单网址
url = f'https://music.163.com/discover/toplist?id={rankId}'
# 向网页发起请求
response = requests.get(url, headers=headers)
# 返回网页内容
return response.text
def get_music(htmlContent):
"""
获取歌曲
:param htmlContent: 网页内容
:return: 返回获取的id和标题列表
"""
# 获取歌曲的id和标题
musicInfo = re.findall(r'<a href="/song\?id=(\d+)">(.*?)</a>', htmlContent)
return musicInfo
def downloadMusic(name, InfoList):
"""
下载歌曲
:param name: 文件名
:param InfoList: 歌曲的id和标题列表
:return:
"""
for music_id, music_title in tqdm(InfoList):
# 歌曲的url
music_url = f'https://music.163.com/song/media/outer/url?id={music_id}.mp3'
music = requests.get(music_url, headers=headers).content
# 将获取的歌曲存储在文件夹中
with open(name + '\\' + music_title + '.mp3', 'wb') as f:
f.write(music)
if __name__ == '__main__':
filename = input('请输入榜单名称: ')
createFolder(filename)
rank_id = input('请输入榜单id: ')
html = get_html(rank_id)
# 歌曲信息列表
musicInfoList = get_music(html)
# 下载音乐
downloadMusic(filename, musicInfoList)

运行前准备
- 安装依赖包:
pip install requests tqdm
- 更新Cookie:
- 由于网易云音乐的反爬机制,Cookie可能会过期
- 建议在运行前,从浏览器中获取最新的Cookie替换到代码中
- 获取方法:在浏览器中登录网易云音乐,按F12打开开发者工具,在Network选项卡中找到请求头中的Cookie
如何使用
-
获取榜单ID:
- 打开网易云音乐官网,进入任意榜单页面
- 从URL中获取榜单ID,例如:
https://music.163.com/discover/toplist?id=3778678中的3778678就是榜单ID
-
运行程序:
python netease_music_downloader.py -
输入信息:
- 根据提示输入榜单名称(用于创建文件夹)
- 输入榜单ID
-
查看结果:
- 程序会自动创建以榜单名称命名的文件夹
- 所有歌曲会下载到该文件夹中
常见榜单ID参考
| 榜单名称 | 榜单ID |
|---|---|
| 热歌榜 | 3778678 |
| 新歌榜 | 3779629 |
| 飙升榜 | 19723756 |
| 电音榜 | 10520166 |
| 古典音乐榜 | 71385702 |
| 欧美热歌榜 | 60198 |
| 韩国流行榜 | 11641012 |
| 日本流行榜 | 60131 |
总结
这个网易云音乐榜单歌曲批量下载器项目展示了如何使用Python的requests和re库进行简单的网页爬虫和文件下载操作。通过这个项目,你可以轻松下载网易云音乐任意榜单中的所有歌曲,方便离线收听。
希望本文对大家学习Python爬虫和文件下载有所帮助!
更多推荐
所有评论(0)