和我一起加入CSDN----程序猿和攻城狮的社区

网易云音乐是我比较喜欢的一个音乐平台,对于特别热爱听歌的人来说,网易云音乐精准的音乐定位和独特歌曲推荐,让人使用起来很舒服。所谓:自古评论出人才,精彩的评论也为歌曲增添不少色彩。


程序描述:爬取网易热歌榜的200首歌曲,获取他们的热门评论并分别写入以歌名为名字的文本文件。


那个。。。我也就不多比比,直接开整


一.python环境与模块

环境:Python3

用到的模块(库):

  1. re 正则表达式:被用来检索、替换那些符合某个模式(规则)的文本
  2. os 用于访问操作系统功能的模块(这里处理文件)
  3. json 编码和解码 JSON 对象
  4. urllib 功能强大、用于操作URL,做爬虫的时候经常会用到的库

二.分析数据和讲解

首先我们先打开网易云音乐网页端,别问我为什么不打开网易云音乐的客户端或者移动端,我不想说~
emmmm,好吧,主要是对于一个才入门Python的新人来说,爬客户端和移动端,似乎有点~难啊 ~。 ~

点击排行榜 选择云音乐热歌榜,进入到我们准备爬取的热歌榜歌单

我们随便选择一首进去查看评论的数据的保存位置(这里我选择了最近比较热的《盗将行》)



2.1 歌曲的数据分析

F12打开工作台查看寻找数据

F5刷新之后,
在 XHR中的(XHR:XMLHttpRequest 对象)
反复查看之后,发现评论数据就放在 “R_SO_4_574566207?csrf_token” 的POST请求文件中(“574566207”是歌曲的id,每首歌在云库里会有对应的id)
URL链接是https://music.163.com/weapi/v1/resource/comments/R_SO_4_574566207?csrf_token=

请求头:

请求参数(params&encSeckey):

提交的表单数据,我们会发现表单中需要填两个数据,名称为params和encSecKey。后面紧跟的是一大串字符,换几首歌会发现,每首歌的params和encSecKey都是不一样的,因此,这两个数据可能经过一个特定的算法进行加密过的。关于参数的解析,可以参考大佬的 https://www.zhihu.com/question/36081767 ,这里说一下同一首歌刷新访问,这两个参数也会改变,但这并不影响我们爬取,后面用的时候,复制这两个参数值就完事了。/手动冷漠

 data = {'params':  'QCfIzRlQCL0FmIk5KHOY0K72J9ylled490jTcp4Z+tbnP/ipZUe6ToHXXEw0l3/vyf76g7wO/xjRR/ewWYGHxODt+i0sFFI+9HtyecVNOAW6lOS4lfF/rfKhMPI6dXhVhUumw5rXelLdRqUnhYIl0mlvF0CwwXh6uL5MX1VEEs4U+uaNMy1e9VGziu4lIjr2','encSecKey':'4e70957c065d62659ac6457ed12568ca99b834603c54691b921ce7501a5c3add5465ef900cff347b1f3e1c446d4b14b4ae09a9698913fb9b74a5541c6e6c4508c223fb0135085804980898b9462fff12635a96816b28f94a4060dd8ce12444280f44692e9a3e3d19c5fd6c69fb6ce5766c29a1bab3314ab69a1c6088ac692a5f'}

服务器返回的和评论相关的数据为json格式的,里面含有非常丰富的信息(比如有关评论者的信息,评论日期,点赞数,评论内容等等),我们要的热评就在hotComments里,一首歌的热评一共是15条,如图:


要点分析:

1.拼接URL:https://music.163.com/weapi/v1/resource/comments/R_SO_4_574566207?csrf_token=


http://music.163.com/weapi/v1/resource/comments/R_SO_4_ + hot_song_id + ?csrf_token=

hot_song_id字面意思就是歌曲对应的id,然后将拼接后的字符作为一个url

2.传参向服务器发送请求 ,获取评论文件:
def get_hotComments(hot_song_name,hot_song_id): #获取评论url, data = post_data(hot_song_id)#接收需要发送的参数#post请求表单数据postdata=urllib.parse.urlencode(data).encode('utf8')  #进行编码request=urllib.request.Request(url,headers=header,data=postdata)reponse=urllib.request.urlopen(request).read().decode('utf8')json_dict=json.loads(reponse)   #获取jsonhot_commit=json_dict['hotComments']  #解析&获取json中的热门评论file_operation(hot_song_name,hot_commit) #热评内容处理,保存到本地

所以只要得到歌曲的id,拼接获取评论数据,处理一哈就可以了。



2.2 热歌榜分析

现在去寻找包含歌单歌曲数据的文件

根据热歌榜上面的URL,我就去找了" toplist?id=3778678 "请求文件,
然后就找到了包含歌曲名字和歌曲id的ul列表


利用正则表达式取出含歌曲的Id和名字的ul列表:

  pat1=r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>'result=re.compile(pat1).findall(html)     #用正则表达式进行筛选   得到['xxxx']

再用正则单独匹配得到歌曲名字和歌曲id:

    pat2=r'<li><a href="/song\?id=\d*?">(.*?)</a></li>' #进行歌名筛选pat3=r'<li><a href="/song\?id=(\d*?)">.*?</a></li>'  #进行歌曲ID筛选hot_song_name=re.compile(pat2).findall(result)    #获取所有热门歌曲名称hot_song_id=re.compile(pat3).findall(result)    #获取所有热门歌曲对应的Id

要点分析

1.正则匹配,获取歌名和歌曲id

当然也可以用其他方式去获取,这里我就不说了。这里用正则,主要是 .*? 很容易就匹配到我们想要的两种数据。



2.3 规范文件命名

def replace_name(hot_song_name):#对歌名中字符进行处理rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'   #不能作为文件名的字符hot_song_name = re.sub(rstr, "_", hot_song_name)  # 替换为下划线return hot_song_name

没错,我还是用的正则。
我的目标的是每首歌曲的评论都保存在一个命名为歌曲名字的txt文本中,到时有些歌曲含有特殊字符 / \ : * ? " < > | ,例如:中含有“/”,这些字符不能作为命名字符的,所以需要更改,否则会报错。这里我把字符替换为了“_”。



2.4 热评写入,OS操作

def file_operation(hot_song_name,hot_commit):#文件操作/将每首歌的评论单独写成文件path = os.getcwd() + '\\song_comments'if not os.path.exists(path):   #如果路径不存在,则创建目录(文件夹)os.makedirs(path)hot_song_name = replace_name(hot_song_name)  #调用replace_name()规范文件命名file = open('song_comments' + '/' + hot_song_name + '.txt', 'a', encoding='utf8')     # 打开文件(追加,'a'),没有则创建file.write(hot_song_name + ':' + '\n')num = 0for item in hot_commit: #写入评论内容num += 1file.write(str(num) + '.' + item['content'] + '\n')#写入评论file.write('\n==================' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + '=====================\n\n')  #(这里并没有清除原内容,每次写入附上日期)file.close()

我的想法是就像上面说的一样,保存成单独的txt文件,我想查看某些歌曲的热评时,直接点开它的评论文本,就不需要看其他歌曲的,当然如果想保存其他形式,把这个 file_operation 函数改一下就行了

三.上代码

口水话说的差不多了,我们直接上代码:

import re
import urllib.request
import urllib.error
import urllib.parse
import json
import os
import time#爬取网易云音乐热歌榜200首热歌的精彩评论(实时,每周四更新) header = {  # 请求头部,表示一哈尊重,虽然对后台大佬来说可能没什么暖用'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0'
}
def get_all_hotSong():     #获取热歌榜所有歌曲名称和idurl='http://music.163.com/discover/toplist?id=3778678'    #网易云云音乐热歌榜urlrequest=urllib.request.Request(url=url, headers=header)html=urllib.request.urlopen(request).read().decode('utf8')   #打开urlhtml=str(html)pat1=r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>'  #进行第一次筛选的正则表达式result=re.compile(pat1).findall(html)     #用正则表达式进行筛选   得到['xxxx']result=result[0]     #获取tuple的第一个元素    取出xxxxxpat2=r'<li><a href="/song\?id=\d*?">(.*?)</a></li>' #进行歌名筛选pat3=r'<li><a href="/song\?id=(\d*?)">.*?</a></li>'  #进行歌曲ID筛选hot_song_name=re.compile(pat2).findall(result)    #获取所有热门歌曲名称hot_song_id=re.compile(pat3).findall(result)    #获取所有热门歌曲对应的Idreturn hot_song_name,hot_song_iddef replace_name(hot_song_name):#对歌名中字符进行处理rstr = r"[\/\\\:\*\?\"\<\>\|]"  # '/ \ : * ? " < > |'   #不能作为文件名的字符hot_song_name = re.sub(rstr, "_", hot_song_name)  # 替换为下划线return hot_song_namedef file_operation(hot_song_name,hot_commit):#文件操作/将每首歌的评论单独写成文件path = os.getcwd() + '\\song_comments'if not os.path.exists(path):   #如果路径不存在,则创建目录(文件夹)os.makedirs(path)# with open(path + '/' + hot_song_name + '.txt', 'w') as f:#     f.write(hot_song_name+':'+'\n')hot_song_name = replace_name(hot_song_name)  #调用replace_name()规范文件命名file = open('song_comments' + '/' + hot_song_name + '.txt', 'a', encoding='utf8')     # 打开文件(追加,'a'),没有则创建file.write(hot_song_name + ':' + '\n')num = 0for item in hot_commit: #写入评论内容(这里并没有清除原内容,每次写入附上日期)num += 1file.write(str(num) + '.' + item['content'] + '\n')#写入评论file.write('\n==================' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + '=====================\n\n')file.close()#关闭文件是个好习惯def post_data(hot_song_id): #向网页发送的请求数据()url = 'http://music.163.com/weapi/v1/resource/comments/R_SO_4_' + hot_song_id + '?csrf_token='  # 歌评urldata = {'params':  'QCfIzRlQCL0FmIk5KHOY0K72J9ylled490jTcp4Z+tbnP/ipZUe6ToHXXEw0l3/vyf76g7wO/xjRR/ewWYGHxODt+i0sFFI+9HtyecVNOAW6lOS4lfF/rfKhMPI6dXhVhUumw5rXelLdRqUnhYIl0mlvF0CwwXh6uL5MX1VEEs4U+uaNMy1e9VGziu4lIjr2','encSecKey':'4e70957c065d62659ac6457ed12568ca99b834603c54691b921ce7501a5c3add5465ef900cff347b1f3e1c446d4b14b4ae09a9698913fb9b74a5541c6e6c4508c223fb0135085804980898b9462fff12635a96816b28f94a4060dd8ce12444280f44692e9a3e3d19c5fd6c69fb6ce5766c29a1bab3314ab69a1c6088ac692a5f'}#说明一下,每次访问时,加密后的params和encSecKey的数据都不一样,但这不影响你获取数据,随便复制用一个就行return url,header,datadef get_hotComments(hot_song_name,hot_song_id): #获取评论url, data = post_data(hot_song_id)#接收请求参数#post请求表单数据postdata=urllib.parse.urlencode(data).encode('utf8')  #进行编码request=urllib.request.Request(url,headers=header,data=postdata)reponse=urllib.request.urlopen(request).read().decode('utf8')json_dict=json.loads(reponse)   #获取jsonhot_commit=json_dict['hotComments']  #解析&获取json中的热门评论file_operation(hot_song_name,hot_commit) #热评内容处理,保存到本地if __name__ == '__main__':hot_song_name, hot_song_id = get_all_hotSong()  #获取热歌榜所有歌曲名称和idnum = 0while num < len(hot_song_name):  # 保存所有热歌榜中的热评print('正在抓取第{}首歌曲《{}》的热评...' .format ((num + 1),(hot_song_name[num])))get_hotComments(hot_song_name[num], hot_song_id[num])print('《{}》的热评抓取成功'.format((hot_song_name[num])))num += 1print('您现在可以查看歌曲的评论了



差不多就这个样子了,更多功能等待你去开发哟~



尾言:

写爬虫不免被反,更有甚者,封IP,拉黑什么的时有发生。多了解一下爬虫与反爬虫,对看官您大有好处。学海无涯苦做舟,感谢你的浏览,希望我的博客能帮助到你。



友情链接:感谢各位大佬

知乎:平胸小仙女 (https://www.zhihu.com/question/36081767)
CSDN:sixu_9days (https://blog.csdn.net/sixu_9days/article/details/80780916)
CSDN:Python开发者 (https://blog.csdn.net/iodjSVf8U1J7KYc/article/details/83005883)
CSDN: 行者刘6 (https://blog.csdn.net/qq_38282706/article/details/80251666)
CSDN:阿阿阿阿阿阿鑫(https://blog.csdn.net/fengxinlinux/article/details/77950209)



Python3---站在大佬肩膀写爬虫-爬取网易云音乐热歌榜歌曲热评(精彩评论)相关推荐

  1. python爬虫爬取网易云音乐歌曲_Python网易云音乐爬虫进阶篇

    image.png 年前写过一篇爬网易云音乐评论的文章,爬不了多久又回被封,所以爬下来那么点根本做不了什么分析,后面就再改了下,加入了多线程,一次性爬一个歌手最热门50首歌曲的评论,算是进阶版了- 思 ...

  2. python网易云_用python爬虫爬取网易云音乐

    标签: 使用python爬虫爬取网易云音乐 需要使用的模块 只需要requests模块和os模块即可 开始工作 先去网易云音乐网页版找一下你想要听的歌曲点击进去.按键盘F12打开网页调试工具,点击Ne ...

  3. python爬虫----爬取网易云音乐

    使用python爬虫爬取网易云音乐 目录 使用python爬虫爬取网易云音乐 需要使用的模块 开始工作 运行结果 需要使用的模块 只需要requests模块和os模块即可 开始工作 先去网易云音乐网页 ...

  4. python网络爬虫网易云音乐下载_python网络爬虫爬取网易云音乐

    #爬取网易云音乐 url="https://music.163.com/discover/toplist" #歌单连接地址 url2 = 'http://music.163.com ...

  5. [爬虫]Python爬取网易云音乐搜索并下载歌曲!

    Python爬取网易云音乐搜索并下载歌曲! 文章目录 Python爬取网易云音乐搜索并下载歌曲! 1.准备工作 2."实地"观察 3.开始码代码! 4.搜索并下载 结束语 1.准备 ...

  6. PHP爬虫爬取网易云音乐热门评论

    说起爬虫,恐怕第一个想到的都是Python,PHP的就少之又少. 得空闲下来,自己用PHP做了一个爬虫,爬取网易云音乐的热门评论. 效果图: 下面简单说一下思路 首先,在网易云官网排行榜内,审查元素, ...

  7. Python爬虫—爬取网易云音乐【热歌榜】歌曲的精彩评论(写入txt文本文件或者MySQL数据库)

      最近在学Python爬虫,看了Blibili爬取网易云音乐评论的视频,视频中是将一首歌的评论存入json文件,我在此代码的基础上扩展了三点:     1.爬取热歌榜200首歌曲的精彩评论:     ...

  8. 如何用Python网络爬虫爬取网易云音乐歌曲

    今天小编带大家一起来利用Python爬取网易云音乐,分分钟将网站上的音乐down到本地. 跟着小编运行过代码的筒子们将网易云歌词抓取下来已经不再话下了,在抓取歌词的时候在函数中传入了歌手ID和歌曲名两 ...

  9. python爬虫爬取网易云音乐歌曲_如何用爬虫获取网易云音乐歌单中的歌曲?

    --------------------------------- 泻药,以我抓取了307835首网易云音乐的歌单歌曲的经验,讲一下这个问题. 喜欢用Github的可以直接看我的项目源码,代码简单.具 ...

最新文章

  1. leetcode--最长回文子串--python
  2. 心中的狂野--最近的感想
  3. [T-ARA][Bo Peep Bo Peep]
  4. Ubuntu 下安装 nfs
  5. MySQL:给表的某个字段添加唯一性约束
  6. Can you raed it croretcly?
  7. SAP Cloud Platform certificate trust下载和business role创建
  8. input和raw_input
  9. 算法竞赛入门经典 例题6-2 铁轨(C、python)
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的汽车租赁系统
  11. Linux gcc编译时强制链接并依赖一个库(即使未使用)
  12. Scan chain/SE,SI,SO 带scan的寄存器
  13. Android电话本实现
  14. 什么是王道?什么是王道中的王道?
  15. Xmanager Xbrowser--Win10远程连接CentOS7
  16. html图片轮播代码 贴吧,JS实现简易图片轮播效果的方法
  17. 怎么才能制作一个比较好的网站
  18. 在线电影订票系统 - 数据库建模
  19. 【信号与系统】5. 系统的特性、LTI系统分析
  20. NLP领域论文笔记【研一下研二上】01

热门文章

  1. python是自由开放源代码软件_开放源代码定义之历史篇
  2. Python网络爬虫——爬取和分析NBA球员排名及各项数据
  3. 通俗易懂告诉你CPU/GPU/TPU/NPU...都是什么意思?
  4. 常用的三种白平衡算法整理
  5. web前端CSS选择符:表示要定义样式的对象
  6. 读书笔记-kafka常用操作命令-kafka-topics.sh
  7. 每天3分钟知晓天下事,一句话新闻资讯简报的公众号推荐
  8. This must be due to duplicate classes or playing wrongly with class loaders 1
  9. win10麦克风权限无法开启
  10. Redis基础进阶--Sentinel 机制与用法(二)