三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

网易云音乐评论爬虫实战:加密破解与数据分析

网易云音乐评论爬虫实战:加密破解与数据分析

1. 为什么选择网易云评论作为爬虫学习目标

网易云音乐的评论区一直以"有故事"著称,这里汇聚了大量用户真实情感表达。从数据角度看,每条评论包含用户ID、昵称、评论内容、点赞数、时间戳等结构化数据,同时评论内容本身又具有丰富的非结构化特征,这种混合数据类型非常适合作为爬虫练手项目。

我最初选择这个项目,是因为它完美覆盖了爬虫技术的几个关键学习点:

  • 需要处理动态加载内容(网易云采用Ajax分页)
  • 涉及加密参数破解(常见的paramsencSecKey加密)
  • 需要模拟登录获取完整数据(部分敏感评论需登录)
  • 数据清洗复杂度适中(包含HTML标签、特殊符号、emoji等)

2. 环境准备与工具选型

2.1 基础环境配置

推荐使用Python 3.8+环境,主要依赖库包括:

requests==2.28.1 # 网络请求 pycryptodome==3.15.0 # AES加密 pandas==1.5.3 # 数据存储 tqdm==4.64.1 # 进度条显示

注意:不要使用最新版requests库,某些版本与网易云API存在兼容性问题。实测2.28.1版本最稳定。

2.2 开发工具选择

建议使用Chrome开发者工具分析网络请求,重点关注:

  • XHR类型的请求(通常包含评论数据)
  • Headers中的csrfCookie字段
  • Form Data中的加密参数

3. 逆向分析关键加密逻辑

3.1 加密参数定位

通过抓包可以发现,获取评论的API请求包含三个关键加密参数:

params = "加密字符串A" encSecKey = "加密字符串B" csrf_token = "从Cookie中获取"

3.2 AES加密逆向

网易云使用AES-128-CBC模式加密,关键参数如下:

  • 密钥:0CoJUm6Qyw8W8jud
  • 初始向量:0102030405060708
  • 二次加密密钥:随机16位字符串

加密过程Python实现:

from Crypto.Cipher import AES import base64 def aes_encrypt(text, key, iv): pad = 16 - len(text) % 16 text = text + pad * chr(pad) cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode()) encrypted = cipher.encrypt(text.encode()) return base64.b64encode(encrypted).decode()

3.3 RSA加密处理

encSecKey采用RSA加密,公钥固定为:

-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7uVEBrdxR6aR5mDZU03kJ9b4IeA5sGTMp8YqomZ5HAYGHJDVd0s0qD0wIDAQAB -----END PUBLIC KEY-----

4. 完整爬虫实现流程

4.1 获取歌曲ID

首先需要获取目标歌曲的ID,有两种方式:

  1. 从网页URL直接提取(如https://music.163.com/#/song?id=123456)
  2. 通过搜索API获取(需处理搜索结果的分页和排序)

推荐使用官方搜索接口:

search_url = "https://music.163.com/api/search/get/web" params = { "s": "歌曲名", "type": 1, # 1表示歌曲 "limit": 5 }

4.2 构造加密请求

实现加密参数生成函数:

def generate_params(text): first_pass = aes_encrypt(text, primary_key, iv) second_pass = aes_encrypt(first_pass, random_key, iv) return second_pass def generate_encSecKey(random_key): # RSA加密实现 ...

4.3 处理分页逻辑

网易云评论采用"瀑布流"加载方式,每页获取20条评论。关键参数:

  • offset: 起始位置
  • total: 总评论数(首次请求返回)
  • limit: 每页数量(固定20)

分页请求示例:

comment_url = "https://music.163.com/weapi/v1/resource/comments/R_SO_4_{song_id}" data = { "params": generate_params(json.dumps({ "rid": f"R_SO_4_{song_id}", "offset": offset, "total": "true" if offset == 0 else "false", "limit": 20 })), "encSecKey": generate_encSecKey(random_key) }

5. 数据存储与分析

5.1 原始数据存储

建议使用CSV格式存储,字段包括:

[ "comment_id", "user_id", "nickname", "content", "liked_count", "time", "ip_location", "reply_count", "beReplied" ]

5.2 数据清洗要点

常见清洗需求:

  • 处理HTML标签(如<em>表情标签)
  • 过滤特殊字符(换行符、制表符等)
  • 提取emoji Unicode编码
  • IP地址归属地解析

5.3 简单分析示例

使用pandas进行基础分析:

import pandas as pd df = pd.read_csv('comments.csv') # 点赞TOP10评论 top10 = df.sort_values('liked_count', ascending=False).head(10) # 按小时统计评论量 df['hour'] = pd.to_datetime(df['time']).dt.hour hour_dist = df.groupby('hour').size()

6. 反爬策略与应对方案

6.1 常见反爬机制

网易云采用的多层防御:

  1. 请求频率限制(单IP约150次/分钟)
  2. 加密参数时效性(约30分钟失效)
  3. 用户行为检测(鼠标轨迹、点击模式)

6.2 应对建议

  1. 请求间隔优化:
import random time.sleep(random.uniform(0.5, 1.5)) # 随机延迟
  1. IP代理池搭建:
  • 使用免费代理(快代理、西刺代理)
  • 付费代理服务(按需购买)
  1. 请求头随机化:
headers = { 'User-Agent': random.choice(user_agent_list), 'Referer': 'https://music.163.com/' }

7. 项目扩展方向

7.1 情感分析应用

使用SnowNLP进行评论情感值计算:

from snownlp import SnowNLP def get_sentiment(text): return SnowNLP(text).sentiments df['sentiment'] = df['content'].apply(get_sentiment)

7.2 用户画像构建

基于评论数据可以分析:

  • 活跃时间段分布
  • 常用表情/词汇
  • 社交关系网络(通过回复关系)

7.3 可视化展示

使用Pyecharts生成:

  • 热词云图
  • 情感趋势折线图
  • 地域分布地图

我在实际爬取中发现,凌晨时段的评论情感值普遍高于白天,这可能与用户夜间情绪状态有关。一个实用的技巧是:对于热门歌曲,可以先爬取前500条热评进行快速分析,再决定是否采集全量数据。

← 返回列表