前言

网易云音乐这款音乐APP本人比较喜欢,用户量也比较大,而网易云音乐之所以用户众多和它的歌曲评论功能密不可分,很多歌曲的评论非常有意思,其中也不乏很多感人的评论。但是,网易云音乐并没有提供热评排行榜和按评论排序的功能,没关系,本文就使用爬虫给大家爬一爬网易云音乐上那些热评的歌曲。

结果

对过程没有兴趣的童鞋直接看这里啦。

评论数大于五万的歌曲排行榜

首先恭喜一下我最喜欢的歌手(之一)周杰伦的《晴天》成为网易云音乐第一首评论数过百万的歌曲!

通过结果发现目前评论数过十万的歌曲正好十首,通过这前十首发现:

薛之谦现在真的很火啦~

几乎都是男歌手啊,男歌手貌似更受欢迎?(别打我),男歌手中周杰伦、薛之谦、许嵩(这三位我都比较喜欢)几乎占了榜单半壁江山...

《Fade》电音强势来袭,很带感哈(搭配炫迈写代码完全停不下来..)

根据结果做了网易云音乐歌单 :

提示: 评论数过五万的歌曲 歌单中个别歌曲由于版权问题暂时下架,暂由其他优秀版本代替。

高能预警:TOP 29 《Lost Rivers》请慎重播放,如果你坚持播放请先看评论...

过程

1、观察网易云音乐官网页面HTML结构

首页(http://music.163.com/)

歌单分类页(http://music.163.com/discover/playlist)。

歌单页(http://music.163.com/playlist?id=499518394)

歌曲详情页(http://music.163.com/song?id=109998)

2、爬取歌曲的ID

通过观察歌曲详情页的URL,我们发现只要爬取到对应歌曲的ID就可以得到它的详情页URL,而歌曲的信息都在详情页。由此可知只要收集到所有歌曲的ID那么就可以得到所有歌曲的信息啦。而这些ID要从哪里爬呢?从歌单里爬,而歌单在哪爬呢?通过观察歌单页的URL我们发现歌单也有ID,而歌单ID可以从歌单分类页中爬,好了就这样爬最终就能收集到所有歌曲的ID了。

3、通过爬取评论数筛选出符合条件的歌曲

很遗憾的是评论数虽然也在详情页内,但是网易云音乐做了防爬处理,采用AJAX调用评论数API的方式填充评论相关数据,由于异步的特性导致我们爬到的页面中评论数是空,那么我们就找一找这个API吧,通关观察XHR请求发现是下面这个家伙..

响应结果很丰富呢,所有评论相关的数据都有,不过经过观察发现这个API是经过加密处理的,不过没关系...

4、爬取符合条件的歌曲的详细信息(名字,歌手等)

这一步就很简单了,观察下歌曲详情页的HTML很容易就能爬到我们要的名字和歌手信息。

源码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

# encoding=utf8

import requests

from bs4import BeautifulSoup

import os, json

import base64

from Crypto.Cipherimport AES

from prettytableimport PrettyTable

import warnings

warnings.filterwarnings("ignore")

BASE_URL= 'http://music.163.com/'

_session= requests.session()

# 要匹配大于多少评论数的歌曲

COMMENT_COUNT_LET= 100000

class Song(object):

def __lt__(self, other):

return self.commentCount > other.commentCount

# 由于网易云音乐歌曲评论采取AJAX填充的方式所以在HTML上爬不到,需要调用评论API,而API进行了加密处理,下面是相关解决的方法

def aesEncrypt(text, secKey):

pad= 16 - len(text)% 16

text= text+ pad* chr(pad)

encryptor= AES.new(secKey,2,'0102030405060708')

ciphertext= encryptor.encrypt(text)

ciphertext= base64.b64encode(ciphertext)

return ciphertext

def rsaEncrypt(text, pubKey, modulus):

text= text[::-1]

rs= int(text.encode('hex'),16)** int(pubKey,16)% int(modulus,16)

return format(rs,'x').zfill(256)

def createSecretKey(size):

return (''.join(map(lambda xx: (hex(ord(xx))[2:]), os.urandom(size))))[0:16]

# 通过第三方渠道获取网云音乐的所有歌曲ID

# 这里偷了个懒直接从http://grri94kmi4.app.tianmaying.com/songs爬了,这哥们已经把官网的歌曲都爬过来了,省事不少

# 也可以使用getSongIdList()从官方网站爬,相对比较耗时,但更准确

def getSongIdListBy3Party():

pageMax= 1 # 要爬的页数,可以根据需求选择性设置页数

songIdList= []

for pagein range(pageMax):

url= 'http://grri94kmi4.app.tianmaying.com/songs?page=' + str(page)

# print url

url.decode('utf-8')

soup= BeautifulSoup(_session.get(url).content)

# print soup

aList= soup.findAll('a', attrs={'target':'_blank'})

for ain aList:

songId= a['href'].split('=')[1]

songIdList.append(songId)

return songIdList

# 从官网的 发现-> 歌单 页面爬取网云音乐的所有歌曲ID

def getSongIdList():

pageMax= 1 # 要爬的页数,目前一共42页,爬完42页需要很久很久,可以根据需求选择性设置页数

songIdList= []

for iin range(1, pageMax+ 1):

url= 'http://music.163.com/discover/playlist/?order=hot&cat=全部&limit=35&offset=' + str(i* 35)

url.decode('utf-8')

soup= BeautifulSoup(_session.get(url).content)

aList= soup.findAll('a', attrs={'class':'tit f-thide s-fc0'})

for ain aList:

uri= a['href']

playListUrl= BASE_URL+ uri[1:]

soup= BeautifulSoup(_session.get(playListUrl).content)

ul= soup.find('ul', attrs={'class':'f-hide'})

for liin ul.findAll('li'):

songId= (li.find('a'))['href'].split('=')[1]

print '爬取歌曲ID成功 -> ' + songId

songIdList.append(songId)

# 歌单里难免有重复的歌曲,去一下重复的歌曲ID

songIdList= list(set(songIdList))

return songIdList

# 匹配歌曲的评论数是否符合要求

# let 评论数大于值

def matchSong(songId, let):

url= BASE_URL+ 'weapi/v1/resource/comments/R_SO_4_' + str(songId)+ '/?csrf_token='

headers= {'Cookie':'appver=1.5.0.75771;','Referer':'http://music.163.com/'}

text= {'username': '', 'password': '', 'rememberLogin': 'true'}

modulus= '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'

nonce= '0CoJUm6Qyw8W8jud'

pubKey= '010001'

text= json.dumps(text)

secKey= createSecretKey(16)

encText= aesEncrypt(aesEncrypt(text, nonce), secKey)

encSecKey= rsaEncrypt(secKey, pubKey, modulus)

data= {'params': encText,'encSecKey': encSecKey}

req= requests.post(url, headers=headers, data=data)

total= req.json()['total']

if int(total) > let:

song= Song()

song.id = songId

song.commentCount= total

return song

# 设置歌曲的信息

def setSongInfo(song):

url= BASE_URL+ 'song?id=' + str(song.id)

url.decode('utf-8')

soup= BeautifulSoup(_session.get(url).content)

strArr= soup.title.string.split(' - ')

song.singer= strArr[1]

name= strArr[0].encode('utf-8')

# 去除歌曲名称后面()内的字,如果不想去除可以注掉下面三行代码

index= name.find('(')

if index >0:

name= name[0:index]

song.name= name

# 获取符合条件的歌曲列表

def getSongList():

print ' ##正在爬取歌曲编号... ##'

# songIdList = getSongIdList()

songIdList= getSongIdListBy3Party()

print ' ##爬取歌曲编号完成,共计爬取到' + str(len(songIdList))+ '首##'

songList= []

print ' ##正在爬取符合评论数大于' + str(COMMENT_COUNT_LET)+ '的歌曲... ##'

for id in songIdList:

song= matchSong(id, COMMENT_COUNT_LET)

if None != song:

setSongInfo(song)

songList.append(song)

print '成功匹配一首{名称:', song.name,'-', song.singer,',评论数:', song.commentCount,'}'

print ' ##爬取完成,符合条件的的共计' + str(len(songList))+ '首##'

return songList

def main():

songList= getSongList()

# 按评论数从高往低排序

songList.sort()

# 打印结果

table= PrettyTable([u'排名', u'评论数', u'歌曲名称', u'歌手'])

for index, songin enumerate(songList):

table.add_row([index+ 1, song.commentCount, song.name, song.singer])

print table

print 'End'

if __name__== '__main__':

main()

友情提示:随着网易云音乐网站结构、接口、加密方式的更换本代码可能并不能很好的工作,不过过程和原理都是一样的,这里也只是给大家分享一下这一过程啦。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

原文链接:http://www.jianshu.com/p/50d99bd7ed62

python爬取音乐并保存_Python爬取网易云音乐上评论火爆的歌曲相关推荐

  1. python音乐可视化效果_Python数据可视化 | 网易云音乐年度歌曲

    网易云音乐2018年度听歌报告-遇见你,真好. 相信有不少人在上周,应该已经看过自己网易云音乐的年度报告了. 小F也是去凑凑热闹,瞅了一波自己的年度听歌报告. 那么你在云村又听了多少首歌,听到最多的歌 ...

  2. python爬歌词生成词云图_Python爬虫摇滚网易云音乐歌词生成词云图

    我相信经过前三篇文章,大家已经学会了怎么下载歌词和歌曲了.看了我的文章后开始行动起来的应该都享受到音乐的福利了.问一个问题,当你疲惫时,你想提起精神来去工作或者看书,你会选择听什么歌曲让自己兴奋起来呢 ...

  3. 爬取《Five Hundred Miles》在网易云音乐的所有评论

    本文原创发布于微信公众号「极客猴」,欢迎关注第一时间获取更多原创分享 在使用 Ajax 技术加载数据的网站中, JavaScript 发起的 HTTP 请求通常需要带上参数,而且参数的值都是经过加密的 ...

  4. 音乐无界限,听见好时光—网易云音乐Linux版震撼来袭!

    为了带来更好的音乐体验,实现对音乐高品质的追求,经过网易云音乐与深度科技团队长达半年多的联合开发,大家期待已久的网易云音乐正式登陆 Linux 平台! 网易云音乐是一款专注于发现与分享的音乐产品,依托 ...

  5. 解锁网易云音乐小工具_什么?网易云音乐又变灰了

    目前音乐市场主要有三大巨头:酷狗音乐,QQ音乐,网易云音乐.QQ音乐与网易云音乐进入市场都较晚,但是网易云音乐凭借灵活的音乐社交玩法积累了非常多的用户,而QQ音乐凭借着有钱优势,购买了很多音乐版权,网 ...

  6. 网易云音乐称酷狗抄袭计算机,网易云音乐称酷狗抄袭 双方有何恩怨?

    来源标题:网易云音乐谴责酷狗音乐"山寨"其推歌功能.页面设计等 2月2日,网易云音乐在官方微博发布致酷狗音乐的公告,声明酷狗音乐平台"山寨"网易云平台上&quo ...

  7. html网易云音乐图片轮播效果,看网易云音乐如何在界面设计中突出特色功能

    一般观念中一款产品的功能越具特色就会放在越突出的位置,但是如果一款产品层级较深,底层架构复杂导致若干功能优先级并列,那在UI设计中如何做到强化和弱化呢? 作为网易云音乐陈年老粉,不得不说这款产品做的真 ...

  8. python爬虫爬取网易云音乐下载_Python爬虫实践-网易云音乐!没有版权又如何!照样爬取!...

    1.前言 最近,网易的音乐很多听不到了,刚好也看到很多教程,跟进学习了一下,也集大全了吧,本来想优化一下的,但是发现问题还是有点复杂,最后另辟捷径,提供了简单的方法啊! 本文主要参考 python编写 ...

  9. 如何利用python爬虫获取网易云音乐某个歌手简介_Python 爬虫获取网易云音乐歌手信息...

    今天就先带大家爬取网易云音乐下的歌手信息并把数据保存下来. 爬取结果 环境 语言:Python 工具:Pycharm 导包 BeautifulSoup:用来解析源码,提取需要的元素. selenium ...

最新文章

  1. java 抛异常给上级_java异常处理机制(示例代码)
  2. 取java.sql.date日期_JAVA 处理时间 - java.sql.Date、java.util.Date与数据库中的Date字段的转换方法[转]...
  3. 智源伍昱:被AI“耽误”的文艺青年,用技术对抗偏见
  4. 对现有代码的分析方法随想
  5. sklearn自学指南(part41)--使用手册的目录
  6. 川崎机器人c#通讯(转)
  7. python虚拟环境中安装diango_创建python虚拟环境,安装django,创建一个django项目,在项目中创建一个应用(ubuntu16.04)...
  8. 阿里巴巴实习生面试悲惨经历
  9. Word设置每页不同的页眉/修改或去掉页眉横线/页眉标题在横线上下方的设置
  10. 向 webview 添加 userScript
  11. rest-assured一些使用心得
  12. rho是什么 matlab,RHO值是什么?如何理解RHO值?
  13. 用IE浏览器打开网址https显示不能访问怎么办
  14. 基于verilog 实现的DDS的发生器
  15. java 电商 插件 开发_JAVA项目实战开发电商项目案例(六与七)商品分类与商品模块管理开发...
  16. 【学习笔记】Splay
  17. MATLAB参数估计
  18. linux 字体 命令,Linux下的字体
  19. Hadoop3 - HDFS 文件存储策略
  20. Adobe After Effects

热门文章

  1. 【部分博客已搬家至博客园】对CSDN、博客园和简书的一点比较
  2. 魔术师发牌问题和拉丁方阵问题
  3. 手机盾、FIDO间的较量
  4. 《The DeadLine》(《最后期限》) 读后感
  5. java井字棋ai_JavaScript实现一个带AI的井字棋游戏源码
  6. 基于JAVA社区志愿者服务管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
  7. SOLIDWORKS配置应用之尺寸配置
  8. 下学期计算机教学工作计划,计算机教学计划范文3篇
  9. Java 集合之给ArrayList排序
  10. SQL Server 数据库之SQL Server 数据库的安全设置