1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python爬取网易云音乐评论并制作词云

python爬取网易云音乐评论并制作词云

时间:2018-09-19 08:22:07

相关推荐

python爬取网易云音乐评论并制作词云

这几天一直在想我还没爬取过的网站,以及会遇到的难点。

每天使用网易云听歌,想着选首喜欢的歌去爬爬它的评论,我是用《小宇》这首歌做实例的。

爬虫写的多了,自然也知道在源码里面找不到的数据,基本上都是动态加载出来的,这个时候我一般会打开网页右击检查(我一般使用的都是Google浏览器),选中它的NetWork,上图(不知道为什么粘贴下来的图片这样别扭)。选中XHR(感觉一直用这个还不知道是啥意思,特意去百度了一波,详情链接:

/ajax/ajax_xmlhttprequest_create.asp),然后我是挨个去点击每个请求的,查看它的内容有哪些,评论内容在里面,就是找到这个接口了,这些都是很好找的。

找到接口后,第一反应是复制链接打开看一下(我的Google浏览器有一个查看json文件的扩展程序JSON-handle,复制链接能直接格式化json内容),却是啥都没有,看了一下请求方式,竟然是post请求,对于post请求的解决我还是不够熟练的。我知道会有个form表单需要提交去请求,具体的原理我还没有摸透,还需好好学习进步一波。

往下翻你会看到一个Form Data,它就是我们要提交的表单,但是两个参数params和encSecKey的值会因为刷新页面而改变的,我查了很多大佬的博客,说是采用了 AES,rsa 加密算法,对数据进行了两次 AES 加密等等,所以需要解密,但是渣渣的我还是没能搞明白那个解密的方式,就根据大佬的提示啥的采用了另一种方式解决了评论的爬取。

代码我在下面粘上了,我都写了注释,其中获取精彩评论是使用我知道的最简单的表单提交的方法请求的,获取全部评论是根据链接/api/v1/resource/comments/R_SO_4_410714325?limit=2920&offset=2939写的循环代入limit和offset两个参数,其实这个并没有完全实现自动化的原则。后面都是同样的方式将请求的json内容转成我们常用的字典形式获取相应的内容,我主要是抓取了用户头像、用户id、用户名、评论时间、获赞的数量、评论内容。

后面将获取的评论文件制作词云的代码也在下面了,也是我这两天到处查资料琢磨的,它主要依靠wordcloud包来制作的,依靠matplotlib包来展示,PIL和numpy是为了设置背景图片而导入的:

pip install wordcloud

pip install matplotlib

pip install PIL

pip install numpy

最后附上我使用的背景图片

代码如下:

# -*- coding:utf-8 -*-"""# @PROJECT: Study# @Author: admin# @Date: -09-04 17:02:43# @Last Modified by: admin# @Last Modified time: -09-04 17:02:43"""import requestsimport jsonimport csvimport timeheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36",}# 获得接口,解析评论接口def parse_comments_json(comments_list, path):for hotComments in comments_list:print("==============================================")user_icon = hotComments.get('user').get('avatarUrl')print("user_icon: ", user_icon)userId = hotComments.get('user').get('userId')print("userId: ", userId)user_nickname = hotComments.get('user').get('nickname')print("user_nickname: ", user_nickname)comment_time = hotComments.get('time')print("comment_time: ", comment_time)comment_time = time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(float(comment_time)/1000))print(comment_time)zan_count = hotComments.get('likedCount')print("zan_count: ", zan_count)comment_content = hotComments.get('content')print("comment_content: ", comment_content)try:# 读写文件with open(path, 'a+', encoding='utf-8') as f:f.write(str(userId) + ";" + user_nickname + ";" + comment_content + ";" + str(zan_count) + ";" + user_icon + "; " + comment_time + "\n")# f.write(comment_content + "\n")# # csv文件# with open('comment.csv', 'a+', encoding='gbk') as f:#writer = csv.writer(f)##writer.writerow([userId, user_nickname, comment_content, zan_count, user_icon, comment_time])except Exception as e:pass# with open('load_error.txt', 'a+', encoding='utf-8') as f:#f.write("==============="+str(e)+"\n")#writer = csv.writer(f)#writer.writerow([userId, user_nickname, comment_content, zan_count, user_icon, comment_time])# 获取精彩评论def get_wangyiyun_hotcomments(url, path):data = {"params": "fe0TVdyT+VuJ55uu+LgTsXlea7dROxXPYGv/FVSJMsm6Vh4nDodf59/qk0EnA/ZcFV7ZfzseLNQgnx7P/7Xnmg0mAO5kMVzNIoGwXr4ya8ZtkS0pU2b9/qwzszDgXp5LyJ8BxOJh6ZqcPFl8Vm7pF8ZpwiKlkPbRACtUnZmzdSEIK1vTXK2Lhlm4nDlw2K2tzNvYRiSesRApZZqBYJqBBvEMu4w/2dICbq8C10GkT1EZY4sX9irB/e7gOrzbYcAVm4pGDSuSWTdG+KoAg4+nCV0wAw2u4IBXw1J/c8tRXfsy0UhM/RrT/ABCHWrndb64mR/nsjResiTbTblHR9EwBh6knLSneQR/0PacjB7Zp6tLlbvhLCAENhTgMfmyRuu1qNb0unshrC/su5u48suwyRdwzCCZIQC/D1atjYpyUirEwBkyFqHN0OVeSsWZf5XjeXyIkJcXZUOu+/kGrYWrm6sLSqGqzJXgYeTYvoHaX0w=","encSecKey": "13948d0b5288185467075eb5bbc36b66759c6cc8ee6cb4676016c47fb114d135fb4225c7072fab489e30ba63af1cc8f2852444d8989064958df436c498a18a7a3c43f290a053021ae0d8653b5f3f27dbb8b3a705ddaa7b9060124c86e065a493ceb4595fe5c6ea1e97ea301d4f6f774e5a5051747cda4d84af2180078fe8c8f5",}# postdata = requestsresp = requests.post(url, data=data, headers=headers)# print(resp.text)comments_dict = json.loads(resp.text)hotComments_list = comments_dict.get('hotComments')print(hotComments_list)parse_comments_json(hotComments_list, path)# 获取全部评论def get_wangyiyu_comments(url, path):header = {'Accept': "*/*",'Accept-Language': "zh-CN,zh;q=0.9",'Connection': "keep-alive",'Host': "",'User-Agent': "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36"}# get_url = '/api/v1/resource/comments/R_SO_4_410714325'n = 1for i in range(0, 125290, 20):param = {'limit': str(i),'offset': str(n * 20 - 1)}n += 1response = requests.post(url, headers=header, params=param)# print(response.text)comments_dict = json.loads(response.text)comments_list = comments_dict.get('comments')print(comments_list)parse_comments_json(comments_list, path=path)# 制作评论词云def draw_wordcloud(path):from wordcloud import WordCloud, ImageColorGeneratorfrom PIL import Imageimport matplotlib.pyplot as pltimport numpy as npbg_mask = np.array(Image.open('bg1.jpg'))text = open(path, encoding='utf-8').read()my_wordcloud = WordCloud(background_color='white', # 设置背景颜色mask=bg_mask,# 设置背景图片max_words=2000, # 设置最大显示的字数font_path=r'C:\Windows\Fonts\STZHONGS.TTF',# 设置中文字体,使的词云可以显示max_font_size=250, # 设置最大字体大小random_state=30, # 设置有多少种随机生成状态, 即有多少种配色方案)myword = my_wordcloud.generate(text)plt.imshow(myword)plt.axis('off')plt.show()if __name__ == '__main__':# url = "/#/song?id=410714325"url = "/weapi/v1/resource/comments/R_SO_4_410714325?csrf_token="# get_wangyiyun_hotcomments(url)path = 'xiaoyu.txt'start_time = time.time()comments_url = "/api/v1/resource/comments/R_SO_4_410714325" # 小宇get_wangyiyu_comments(comments_url, path)end_time = time.time()print("程序耗时%f秒." % (end_time - start_time))draw_wordcloud(path)

【注意】 尽量使用代理ip,不然访问多了会封IP的

写到这里已经完成我想要的功能,并且获取想要的数据了,后续还想用这些数据进行分析,敬请期待!!!

欢迎大家评论和关注

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。