Python 爬虫项目 音乐平台歌单与曲目信息采集

Python 爬虫项目 音乐平台歌单与曲目信息采集 前言网络音乐平台汇聚了海量歌单、单曲、歌手、专辑等音频相关数据这类结构化与半结构化数据在音乐推荐系统、舆情分析、音乐行业数据统计、个性化歌单生成等场景中具备极高的应用价值。传统人工整理音乐数据效率低下、数据覆盖范围有限而依托 Python 爬虫技术能够自动化、规模化地完成歌单列表、曲目名称、演唱者、播放量、收藏量、发行时间、歌词等多维度信息的采集工作。本次实战选取主流音乐平台作为目标站点围绕公开歌单与曲目核心信息开展合规数据爬取全程基于通用爬虫技术栈实现兼顾代码通用性、运行稳定性与数据完整性。文章会从环境依赖、站点接口分析、请求伪装、数据解析、数据存储、异常处理、反爬规避、代码优化等多个维度展开讲解搭配完整可运行代码、原理剖析、参数说明与实战踩坑总结。为方便读者快速搭建运行环境、下载对应依赖库与工具现将本文用到的所有第三方库官方地址、安装源链接统一整理如下requests网络请求库https://pypi.org/project/requests/beautifulsoup4网页解析库https://pypi.org/project/beautifulsoup4/lxml解析引擎配合 BeautifulSoup 使用https://pypi.org/project/lxml/jsonPython 内置 JSON 解析库Python 标准库无需额外安装https://docs.python.org/3/library/json.htmlrePython 内置正则表达式库Python 标准库无需额外安装https://docs.python.org/3/library/re.htmlcsvPython 内置 CSV 文件存储库Python 标准库无需额外安装https://docs.python.org/3/library/csv.htmltimePython 内置时间处理库用于请求延时https://docs.python.org/3/library/time.htmlrandomPython 内置随机数库用于随机延时规避反爬https://docs.python.org/3/library/random.htmlfake-useragent随机请求头生成库https://pypi.org/project/fake-useragent/本文所有代码基于 Python 3.8 及以上版本开发测试适配 Windows、Linux、macOS 全平台读者按照链接指引完成依赖安装后即可复现全部功能。同时需要着重强调本次爬虫仅针对平台公开展示的非版权涉密数据进行采集所有操作需严格遵守目标网站《用户协议》与《robots 协议》禁止大规模高频爬取、禁止盗用版权音频文件、禁止将采集数据用于商业侵权行为技术学习与研究需在合法合规的框架内开展。一、项目整体规划与需求分析1.1 项目核心采集目标结合音乐平台页面结构与公开数据维度本次爬虫确定两大核心采集模块歌单基础信息采集、歌单内曲目明细采集细分采集字段如下表所示。表格数据分类采集字段字段说明数据类型歌单基础信息歌单 ID平台唯一标识编号用于关联曲目字符串 / 整型歌单基础信息歌单名称用户创建 / 官方推荐歌单标题字符串歌单基础信息创建者昵称歌单发布用户名称字符串歌单基础信息创建者 ID创作者平台账号编号字符串 / 整型歌单基础信息播放总量歌单累计播放次数整型歌单基础信息收藏数量歌单被用户收藏次数整型歌单基础信息分享数量歌单对外分享次数整型歌单基础信息歌单标签风格、语种、场景等分类标签列表 / 字符串歌单基础信息歌单简介创作者填写的歌单描述内容字符串曲目明细信息曲目 ID单曲唯一标识编号字符串 / 整型曲目明细信息曲目名称歌曲完整名称字符串曲目明细信息歌手名称歌曲演唱艺人多歌手以分隔符区分字符串曲目明细信息专辑名称歌曲所属专辑名称字符串曲目明细信息曲目时长歌曲播放时长格式为分秒字符串曲目明细信息歌曲播放次数单首歌曲累计播放量整型1.2 技术选型说明本项目采用请求 解析 存储经典爬虫架构结合目标站点特征选择对应技术组件各组件分工明确且相互解耦网络请求层使用requests库发送 HTTP/HTTPS 请求替代 Python 原生 urllib 库其语法简洁、支持会话保持、Cookie 携带、代理配置能够高效模拟浏览器请求行为搭配fake-useragent动态生成随机 UA 请求头降低被服务器识别为爬虫程序的概率。数据解析层目标站点同时存在 HTML 静态页面数据与接口返回的 JSON 格式数据因此组合使用两套解析方案。静态网页内容采用BeautifulSoup4搭配lxml解析引擎完成 DOM 节点定位与数据提取接口返回的结构化数据直接使用 Python 内置json库解析对于混杂在 HTML 标签内的不规则文本使用内置re正则表达式库完成匹配提取。防反爬层依托time与random库实现随机请求延时模拟人类浏览行为的时间间隔避免短时间内高频请求触发站点 IP 封禁、验证码拦截等反爬策略。数据存储层优先使用 Python 内置csv库将采集数据写入 CSV 格式文件该格式通用性极强可直接用 Excel、WPS、数据库工具打开查看与二次处理无需额外部署数据库环境适合中小型数据量采集场景。1.3 项目执行流程整个爬虫项目按照线性流程分步执行逻辑清晰且便于模块拆分与故障排查完整流程如下环境准备安装所有依赖第三方库确认 Python 运行环境正常站点分析通过浏览器开发者工具抓包分析歌单列表页、歌单详情页的 URL 规则、请求方式、请求参数、数据返回格式请求封装编写通用请求函数统一配置请求头、超时时间、异常捕获逻辑歌单列表爬取遍历分类歌单页面批量采集所有歌单的基础信息与唯一 ID曲目详情爬取利用歌单 ID 拼接详情页 URL进入对应页面提取每一首曲目的明细数据数据清洗对采集到的空值、特殊符号、换行符、多余空格等脏数据进行统一清洗数据持久化将清洗后的结构化数据按分类写入 CSV 文件完成本地存储异常处理与日志捕获网络超时、页面 404、数据缺失等异常保证程序持续运行程序优化针对爬取速度、反爬规避、代码复用性进行迭代优化。二、开发环境搭建与依赖安装2.1 Python 环境要求本项目代码兼容Python 3.8 ~ Python 3.12全系列版本不支持 Python 2.x 版本。建议使用官方原生 Python 环境也可搭配 Anaconda 虚拟环境管理工具实现多项目环境隔离避免库版本冲突。2.2 第三方库安装命令结合前文给出的库链接读者可通过 Python 包管理工具pip完成一键安装区分常规安装与国内镜像源安装国内网络环境推荐使用镜像源提升下载速度。2.2.1 常规 pip 安装命令打开系统命令行CMD、PowerShell、终端依次执行以下命令bash运行pip install requests pip install beautifulsoup4 pip install lxml pip install fake-useragent2.2.2 国内清华镜像源安装命令推荐国内访问 PyPI 官方源速度较慢使用清华大学开源软件镜像站可大幅提升安装效率命令如下bash运行pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple pip install beautifulsoup4 lxml -i https://pypi.tuna.tsinghua.edu.cn/simple pip install fake-useragent -i https://pypi.tuna.tsinghua.edu.cn/simple2.3 环境校验方法安装完成后在命令行输入python进入 Python 交互式环境执行导入语句验证库是否安装成功若无报错则代表环境搭建完成python运行import requests from bs4 import BeautifulSoup from fake_useragent import UserAgent若提示ModuleNotFoundError说明对应库未安装成功需重新执行安装命令。三、目标站点抓包与接口分析爬虫开发的核心前提是分析目标站点的数据传输逻辑本章节使用 Chrome 浏览器开发者工具完成抓包分析区分静态页面渲染与异步接口加载两种数据形式。3.1 浏览器抓包基础操作打开浏览器进入音乐平台歌单分类页面按下F12键唤起开发者工具切换至 **Network网络** 面板勾选Preserve log保留日志选项刷新当前页面面板内会加载出当前页面所有的请求记录请求记录分为Doc、XHR、JS、CSS、Img等类型其中Doc代表 HTML 主页面XHR/Fetch代表前端异步加载的接口请求也是动态数据的主要来源点击单条请求可查看Request URL请求地址、Request Method请求方式、Request Headers请求头、Query String Parameters请求参数、Response响应内容五大核心信息。3.2 歌单列表页分析主流音乐平台的歌单列表分为分页展示形式URL 具备明显的页码参数特征。经过抓包分析得出以下关键结论请求方式歌单列表页统一为GET请求无复杂 POST 加密参数请求门槛较低URL 规则基础 URL 分页参数格式示例https://xxx.com/playlist?cat全部page1其中page为分页页码修改该参数即可遍历所有分页歌单数据形式歌单名称、创建者、播放量等基础信息一部分直接渲染在 HTML 页面中可通过 BeautifulSoup 解析 DOM 节点提取部分实时播放数据由 XHR 异步接口返回 JSON 格式数据关键 DOM 节点所有歌单条目统一嵌套在同一个 class 属性的 div/li 标签内每一条歌单为独立子节点歌单 ID 隐藏在标签属性、链接地址当中是关联曲目数据的核心字段。3.3 歌单详情页与曲目接口分析点击任意歌单进入详情页面继续抓包分析曲目数据加载逻辑歌单详情页 URL 规则基础详情 URL 歌单 ID格式示例https://xxx.com/playlist?id123456通过列表页提取的歌单 ID 即可拼接出所有歌单详情地址曲目数据加载形式绝大部分平台不会将上百条曲目直接渲染在 HTML 中而是通过异步 XHR 接口分页加载曲目列表接口携带歌单 ID、起始位置、每页条数等参数响应格式曲目数据全部为标准 JSON 格式字段层级清晰包含曲目 ID、歌名、歌手、时长、专辑等所有需要采集的字段解析难度远低于 HTML 页面反爬特征详情页接口存在基础请求头校验缺失User-Agent会直接返回 403 拒绝访问因此请求头伪装是必不可少的环节。3.4 反爬机制总结结合抓包与实测该音乐平台针对普通爬虫设置了基础反爬策略无高强度加密、验证码、指纹校验等复杂反爬主要规则如下校验请求头拒绝无User-Agent的非法请求识别简易爬虫频率限制短时间内连续发送大量请求会触发 IP 临时封禁表现为页面无法访问、接口返回空数据Cookie 校验部分接口需要携带页面 Cookie 才能正常返回数据纯裸请求会数据缺失 基于以上规则本项目采用随机 UA 会话保持 随机延时的组合方案规避反爬。四、通用请求模块开发与原理详解通用请求函数是整个爬虫的基础组件负责统一处理网络请求、请求头伪装、超时控制、异常捕获、会话保持后续所有页面与接口请求都会复用该函数实现代码解耦与复用。4.1 通用请求函数完整代码python运行# 导入所需依赖库 import requests import time import random from fake_useragent import UserAgent # 初始化随机UA对象 ua UserAgent() # 创建会话对象实现Cookie自动携带与会话保持 session requests.Session() def get_page_response(url, timeout10): 通用网络请求函数统一处理GET请求、请求头、延时、异常 :param url: 目标请求地址 :param timeout: 请求超时时间默认10秒 :return: 成功返回响应对象失败返回None # 构建请求头随机生成浏览器UA headers { User-Agent: ua.random, Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9, Referer: https://music.example.com/ } try: # 随机延时1~3秒模拟人类浏览间隔 sleep_time random.uniform(1, 3) time.sleep(sleep_time) # 发送GET请求 response session.get(urlurl, headersheaders, timeouttimeout) # 设置响应编码解决中文乱码问题 response.encoding response.apparent_encoding # 判断请求状态码200代表请求成功 if response.status_code 200: return response else: print(f请求失败状态码{response.status_code}请求地址{url}) return None except requests.exceptions.Timeout: print(f请求超时地址{url}) return None except requests.exceptions.ConnectionError: print(f网络连接异常地址{url}) return None except Exception as e: print(f未知异常{str(e)}请求地址{url}) return None4.2 代码模块原理逐行解析4.2.1 库导入与对象初始化原理from fake_useragent import UserAgent该库内置了海量主流浏览器Chrome、Firefox、Edge、Safari 等的User-Agent字符串ua UserAgent()完成对象实例化后调用ua.random即可每次生成随机 UA避免单一 UA 被服务器标记为爬虫。相较于手动编写固定 UA动态随机 UA 的伪装效果更强。session requests.Session()requests库的会话对象核心作用是会话保持与 Cookie 自动管理。普通requests.get()属于单次独立请求不会保留上一次请求的 Cookie而 Session 对象会自动存储、携带站点下发的 Cookie模拟真实浏览器的会话状态完美适配需要 Cookie 校验的接口与页面。4.2.2 请求头构建原理请求头Headers是客户端向服务器传递的身份标识与访问配置本项目中三个核心请求头作用如下User-Agent告知服务器当前客户端是什么浏览器、操作系统、设备型号是站点最基础的反爬校验项缺失该字段会直接拦截请求。Accept声明客户端能够接收的数据类型模拟浏览器正常的资源接收规则。Referer标识当前请求的来源页面部分站点会校验该字段防止跨站非法请求填写站点首页地址可进一步提升伪装度。4.2.3 随机延时原理random.uniform(1, 3)会生成1 到 3 秒之间的随机浮点数搭配time.sleep()实现随机等待。固定时长延时容易被行为分析系统识别而无规律的随机延时高度模拟人工点击页面的行为特征是规避 IP 频率限制最简单有效的方案。延时区间可根据站点严格程度调整反爬严格的站点可扩大至 2~5 秒。4.2.4 异常捕获原理网络请求属于不稳定 IO 操作存在超时、断网、服务器宕机、页面 404 等多种异常场景代码中使用分层异常捕获requests.exceptions.Timeout捕获请求超时异常当服务器响应速度过慢、网络卡顿超过设定的 timeout 时间后触发requests.exceptions.ConnectionError捕获连接异常对应断网、域名无法解析、服务器拒绝连接等场景通用Exception捕获其余所有未知异常保证程序不会因为单条请求失败而整体崩溃实现容错运行。4.2.5 编码处理原理response.encoding response.apparent_encoding用于解决网页中文乱码问题。部分站点不会在响应头中声明编码格式response.encoding默认识别错误导致中文显示为问号、乱码。apparent_encoding会自动分析网页内容识别真实编码UTF-8、GBK、GB2312 等是 Python 爬虫处理中文乱码的标准解决方案。五、歌单列表信息采集模块开发与原理在通用请求函数的基础上开发歌单列表采集模块实现分页遍历、HTML 数据解析、歌单基础信息提取、数据清洗功能同时将采集结果临时存储为后续曲目爬取提供歌单 ID 数据源。5.1 歌单列表采集完整代码python运行from bs4 import BeautifulSoup import re # 定义全局列表存储所有歌单信息 playlist_list [] def crawl_playlist_list(total_page5): 爬取分页歌单列表信息 :param total_page: 需要爬取的总页数默认爬取5页 :return: 无返回值数据存入全局列表 # 歌单列表基础URLpage为分页参数 base_url https://music.example.com/playlist?cat全部page{} # 正则表达式用于提取标签内数字播放量、收藏量 num_pattern re.compile(r\d) for page in range(1, total_page 1): # 拼接分页URL page_url base_url.format(page) print(f正在爬取第 {page} 页歌单地址{page_url}) # 调用通用请求函数获取页面响应 response get_page_response(page_url) if not response: continue # 使用lxml解析引擎实例化BeautifulSoup对象 soup BeautifulSoup(response.text, lxml) # 定位所有歌单条目父节点 playlist_items soup.find_all(li, class_playlist-item) # 遍历单页所有歌单 for item in playlist_items: # 1. 提取歌单名称 try: playlist_name item.find(a, class_playlist-name).get_text(stripTrue) except: playlist_name 未知歌单 # 2. 提取歌单ID从链接地址中截取 try: playlist_href item.find(a, class_playlist-name)[href] playlist_id num_pattern.search(playlist_href).group() except: playlist_id 0 # 3. 提取创建者昵称 try: creator_name item.find(span, class_creator).get_text(stripTrue) except: creator_name 未知用户 # 4. 提取播放总量 try: play_count_text item.find(span, class_play-count).get_text(stripTrue) play_count num_pattern.findall(play_count_text)[0] except: play_count 0 # 5. 提取收藏数量 try: collect_text item.find(span, class_collect-count).get_text(stripTrue) collect_count num_pattern.findall(collect_text)[0] except: collect_count 0 # 6. 提取歌单标签 try: tag_list item.find_all(span, class_tag) tag_str ,.join([tag.get_text(stripTrue) for tag in tag_list]) except: tag_str 无标签 # 组装单条歌单数据字典 playlist_info { 歌单ID: playlist_id, 歌单名称: playlist_name, 创建者: creator_name, 播放量: play_count, 收藏量: collect_count, 歌单标签: tag_str } # 添加至全局列表 playlist_list.append(playlist_info) print(f歌单列表爬取完成共采集 {len(playlist_list)} 个歌单)5.2 歌单列表模块原理详解5.2.1 分页遍历原理代码中for page in range(1, total_page 1)实现分页循环结合base_url.format(page)动态拼接每一页的 URL。该逻辑基于抓包得到的分页 URL 规则修改total_page参数即可自由控制爬取页数灵活性极强。若站点分页存在最大页数限制可增加页面判断逻辑到达尾页后自动终止循环。5.2.2 BeautifulSoup 节点定位原理BeautifulSoup是 HTML/XML 文档解析工具核心功能是将不规则的 HTML 字符串转化为结构化的 DOM 树通过节点标签、class、id、属性实现精准定位soup BeautifulSoup(response.text, lxml)将页面 HTML 文本传入解析器指定lxml作为解析引擎。lxml 基于 C 语言开发解析速度快、容错性高是生产环境下的首选引擎。soup.find_all(li, class_playlist-item)find_all()方法用于批量查找所有匹配节点参数含义第一个参数为 HTML 标签名class_匹配标签的 class 属性使用 class_是因为 class 为 Python 保留关键字。该语句会一次性获取当前页面所有歌单条目节点。item.find(a, class_playlist-name)find()方法用于查找单个匹配节点只返回第一个符合条件的标签适用于单条数据提取。get_text(stripTrue)提取标签内的纯文本内容stripTrue会自动去除文本首尾的空格、换行符、制表符完成基础数据清洗避免多余空白字符影响后续存储与使用。5.2.3 正则表达式提取原理部分数据如歌单 ID、播放量混杂在 URL 链接、中文文本当中无法通过 DOM 节点直接提取纯数字因此使用re正则库处理num_pattern re.compile(r\d)编译正则表达式规则\d代表匹配一个及以上数字编译后的正则对象可重复使用提升执行效率。num_pattern.search(playlist_href).group()search()方法从字符串中查找第一个匹配规则的内容group()提取匹配到的结果用于从歌单链接中截取纯数字格式的歌单 ID。num_pattern.findall(play_count_text)findall()方法查找字符串中所有匹配规则的内容返回列表适用于从 “播放123 万” 这类混合文本中提取数字。5.2.4 容错与空值处理原理每一个字段提取逻辑都包裹在try...except异常捕获结构中。网页结构可能存在个别条目字段缺失、标签层级变化的情况若直接提取会触发AttributeError报错。捕获异常后为字段赋予默认值未知歌单、0、无标签等保证单条歌单数据异常不会中断整个分页爬取流程进一步强化程序稳定性。5.2.5 数据结构化原理将每一条歌单信息组装为字典格式字典的键对应数据表字段值为采集到的内容。字典是 Python 中最常用的结构化数据载体格式清晰、便于遍历、写入文件或数据库也是后续数据存储模块的标准输入格式。所有歌单字典统一存入全局列表playlist_list实现数据批量管理。六、曲目明细采集模块开发与原理曲目明细是本项目的核心采集内容依托上一模块获取的歌单 ID拼接详情接口地址解析 JSON 格式响应数据提取每一首曲目的完整信息。该模块分为接口请求、JSON 解析、数据清洗三大核心环节。6.1 曲目明细采集完整代码python运行import json # 定义全局列表存储所有曲目信息 track_list [] def crawl_track_info(): 根据歌单ID爬取对应歌单内所有曲目信息 :return: 无返回值数据存入全局列表 # 曲目接口基础URL参数为歌单ID track_api_url https://music.example.com/api/track?playlistId{} # 遍历所有已采集的歌单 for playlist in playlist_list: playlist_id playlist.get(歌单ID) playlist_name playlist.get(歌单名称) print(f正在爬取歌单【{playlist_name}】曲目歌单ID{playlist_id}) # 拼接曲目接口地址 api_url track_api_url.format(playlist_id) # 调用通用请求函数获取接口响应 response get_page_response(api_url) if not response: continue try: # 解析JSON格式响应数据 json_data json.loads(response.text) except json.JSONDecodeError: print(f歌单{playlist_id}接口返回非JSON数据跳过该歌单) continue # 从JSON层级中提取曲目数组 track_array json_data.get(data, {}).get(trackList, []) if not track_array: print(f歌单{playlist_id}暂无曲目数据) continue # 遍历单首曲目 for track in track_array: # 提取曲目基础字段 track_id track.get(trackId, 0) track_name track.get(trackName, 未知曲目) singer track.get(singerName, 未知歌手) album_name track.get(albumName, 未知专辑) duration track.get(duration, 00:00) track_play_count track.get(playCount, 0) # 组装单条曲目数据字典 track_info { 所属歌单ID: playlist_id, 所属歌单名称: playlist_name, 曲目ID: track_id, 曲目名称: track_name, 歌手: singer, 专辑: album_name, 曲目时长: duration, 单曲播放量: track_play_count } track_list.append(track_info) print(f曲目爬取完成共采集 {len(track_list)} 首曲目数据)6.2 曲目采集模块原理详解6.2.1 接口 URL 拼接逻辑该模块的数据源完全依赖歌单列表模块的结果通过playlist.get(歌单ID)取出每条歌单的唯一编号拼接异步接口 URL。这种上下游模块关联的设计是分层爬虫的典型思路先爬取索引数据再根据索引爬取明细数据逻辑分层清晰便于单独调试每一个模块。6.2.2 JSON 数据解析原理目标曲目接口返回标准 JSON 字符串Python 内置json库是解析此类数据的最优选择json.loads(response.text)将接口返回的JSON 格式字符串转换为 Python 字典 / 列表组合的结构化对象转换后可直接通过键取值语法简单、执行效率高。json.JSONDecodeError异常捕获当接口返回空数据、HTML 错误页面、加密文本时字符串不符合 JSON 格式会触发该异常。捕获异常并跳过当前歌单防止程序终止。多层级取值json_data.get(data, {}).get(trackList, [])为安全取值写法。JSON 数据存在多层嵌套get()方法相较于直接[]取值更加安全若上一层键不存在返回默认空字典 / 空列表不会触发键不存在的报错极大提升代码容错性。6.2.3 字段提取与默认值原理track.get(trackId, 0)同样使用get()方法提取字段并设置默认值。部分小众曲目、下架曲目会出现字段缺失的情况设置默认值 “0”“未知曲目” 等保证每一条曲目数据字段完整性统一数据格式为后续存储与数据分析奠定基础。6.2.4 数据关联设计原理曲目字典中额外加入所属歌单ID与所属歌单名称两个字段实现曲目与歌单的关联绑定。在后续数据分析、表格筛选时可通过歌单 ID 反向查询对应的所有曲目完成多表关联逻辑模拟简易数据库外键的设计思想让采集的数据具备业务关联价值。七、CSV 数据存储模块开发与原理数据采集完成后需要将内存中的列表字典数据持久化到本地文件本项目选用 CSV 格式存储编写通用 CSV 写入函数分别存储歌单数据与曲目数据并讲解文件存储的核心原理。7.1 CSV 数据存储完整代码python运行import csv def save_to_csv(data_list, file_name, fieldnames): 通用CSV文件写入函数 :param data_list: 待写入的字典列表数据 :param file_name: 生成的CSV文件名称 :param fieldnames: CSV表头列表对应字典键名 # 使用utf-8-sig编码解决Excel打开中文乱码问题 with open(file_name, w, newline, encodingutf-8-sig) as f: # 创建CSV写入器 writer csv.DictWriter(f, fieldnamesfieldnames) # 写入表头 writer.writeheader() # 批量写入所有数据行 writer.writerows(data_list) print(f数据已成功保存至文件{file_name}) # 主执行函数串联所有爬虫模块 def main(): # 1. 爬取歌单列表爬取前5页 crawl_playlist_list(total_page5) # 2. 爬取所有歌单对应的曲目 crawl_track_info() # 定义歌单CSV表头 playlist_header [歌单ID, 歌单名称, 创建者, 播放量, 收藏量, 歌单标签] # 保存歌单数据 save_to_csv(playlist_list, 音乐平台歌单数据.csv, playlist_header) # 定义曲目CSV表头 track_header [所属歌单ID, 所属歌单名称, 曲目ID, 曲目名称, 歌手, 专辑, 曲目时长, 单曲播放量] # 保存曲目数据 save_to_csv(track_list, 音乐平台曲目数据.csv, track_header) # 程序入口 if __name__ __main__: main()7.2 CSV 存储模块原理详解7.2.1 文件打开编码原理encodingutf-8-sig是 Python 爬虫写入 CSV 文件的标准编码配置。Windows 系统下的 Excel 软件默认使用 GBK 编码解析 CSV 文件若使用普通utf-8编码中文会出现大面积乱码。utf-8-sig会在文件头部添加 BOM 标记兼容 Excel、WPS、记事本等全平台软件完美解决中文乱码问题。newline用于去除 CSV 文件中多余的空行。Windows 系统下使用csv库写入文件时默认会产生换行冗余设置newline可屏蔽该问题保证表格格式整洁。7.2.2 csv.DictWriter 工作原理csv.DictWriter是专门针对字典列表设计的写入器完美适配本项目的数据格式初始化时传入文件对象与fieldnames表头列表表头顺序、名称必须和字典的键一一对应writer.writeheader()单独写入 CSV 第一行表头用于标识每一列数据含义writer.writerows(data_list)批量写入字典列表每一个字典自动转化为表格中的一行数据键对应列表头值对应单元格内容无需手动循环逐行写入代码简洁且执行效率高。7.2.3 模块化串联原理main()函数作为整个爬虫项目的程序入口按照业务流程依次调用歌单爬取、曲目爬取、数据存储三大模块实现功能串联。这种模块化拆分的优势在于可单独运行某一个模块进行调试、可灵活调整执行顺序、后续新增功能如数据清洗、数据库存储可直接在主函数中扩展符合软件工程的模块化开发思想。7.2.4 程序入口判断原理if __name__ __main__是 Python 标准程序入口判断语句当文件直接作为主程序运行时该条件成立执行main()函数当文件被其他 Python 文件作为模块导入时条件不成立不会自动执行爬虫逻辑。该写法让代码既可以独立运行也可以作为工具库被其他项目调用。八、数据清洗、异常优化与项目拓展方案8.1 现有数据脏数据问题与清洗方案实际爬取过程中会产生各类脏数据影响数据可用性结合实战场景整理常见问题与清洗代码数字单位统一平台播放量会出现 “1.2 万”“10 万 ” 等文本格式无法直接用于数值统计。可编写转换函数将中文单位转换为纯数字。特殊符号过滤歌名、歌单名称中存在 emoji、特殊标点、换行符使用正则表达式匹配并过滤。重复数据去重分页爬取可能出现重复歌单 / 曲目通过唯一 ID歌单 ID、曲目 ID进行去重。基础数据清洗示例代码python运行def clean_text(text): 文本清洗函数过滤特殊符号与空白字符 # 过滤emoji与特殊符号 emoji_pattern re.compile([\U00010000-\U0010ffff]) text emoji_pattern.sub(, text) # 去除首尾空格 text text.strip() return text8.2 反爬策略进阶优化针对站点加强反爬后的优化方案在现有代码基础上迭代升级代理 IP 配置当 IP 被封禁后引入代理 IP 池在session.get()中增加proxies参数切换不同 IP 发起请求突破 IP 限制。Cookie 持久化将会话 Cookie 保存至本地文件下次运行程序直接加载 Cookie跳过初始页面校验。请求头完整模拟补充Cookie、Sec-Fetch-*系列请求头完全复刻浏览器请求特征。动态延时梯度访问详情接口时延长延时区分列表页与详情页的等待时间。8.3 项目功能拓展方向本基础项目可基于现有架构进行多维度功能拓展适配不同业务需求歌词采集基于曲目 ID 对接歌词接口抓取歌曲完整歌词拓展文本数据维度。数据库存储将 CSV 存储替换为 MySQL、SQLite、MongoDB 数据库适配海量数据存储与查询场景。增量爬取记录上一次爬取时间与最新歌单 ID实现增量更新避免重复爬取历史数据。多线程 / 异步爬取引入threading、aiohttp实现异步并发请求大幅提升爬取效率并发爬取需严格控制并发数避免恶意攻击站点。数据可视化结合 Matplotlib、Pandas 对采集的播放量、收藏量数据进行统计分析与图表展示。8.4 合规性与运维注意事项严格遵守目标站点robots.txt协议不爬取协议禁止的路径与数据控制爬取频率与并发数量不对站点服务器造成压力禁止爬取版权音频、付费内容、用户隐私信息定期监测站点页面结构与接口变化DOM 节点、URL、参数变更后及时调整代码。