【NLP】利用jieba对网易云音乐的评论进行词云分析
这是一篇代码文章,因为所有的文字将会以类似注释的方式进行叙述,文字是对代码的补充说明和解读。
这是一篇避坑文章,尤其对于新人来说,这些坑你一定会遇到,希望你不会犯下跟我一样的问题,从另一个角度来讲,你们是幸运的。
本文在pycharm里运行,python 版本3.6,在windows 10系统中运行,望周知。
好了,话不多说,开始码代码。
import numpy as npimport timeimport jsonfrom pandas.io.json import json_normalizeimport requestsimport pandas as pdimport jiebafrom PIL import Imageimport wordcloud
上述我应该不需要多说,就是导入需要的模块,貌似有点多,但是也说明这里的坑比较多,接着往下走。
pd.set_option('display.max_columns',None)
第一次利用pandas读取文件时,尤其是字段多到30几个,行数多于几万行,这时会出现如下的景象:
发现列跟行都被省略了,这时你怎么办?你可能回答:我就蹭蹭,我不进去,不好意思,因为文件太大,你没有办法打开物理文件。那么这个时候,一行代码就用上了:
pd.set_option('display.max_columns',None)
用以显示所有列,相应的还有display.max_rows 显示所有行。
当你第一次见到该数据时,你需要对数据的记录或者字段进行一番简单的了解,这个选项能让你对数据有个初步概念。
当然了 pd.set_option里有诸多的选项,在这里不做深究,有兴趣的可以课下公众号搜索一下。
wangyimusic_comments = Nonefor i in range(100,1100,100): url = r'http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=100&offset={}'.format(str(i)) headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'} response = requests.get(url,headers=headers)
- 1、这里把网易云评论的接口拿出来拓展一下
http://music.163.com/api/v1/resource/comments/R_SO_4_{111}?limit={222}&offset={333}
"111":这里是指的歌曲的ID,如果你想下载任意一首歌曲的评论数据,你可以先去网易云搜一下歌曲,对应的网址内就有这个歌曲ID。
"222":这里是可以自己修改的,其实就是一页显示的评论条数,比如你可以是10,100,看你的心情,也得看后面的offset设置的简单与否。
毕竟你要爬取多页的数据,不能自己给自己找麻烦对吧。
"333":指的是从哪一条评论开始下一页,比如100,意味着从第100条评论开始下一页。如果你对数据库的分页limit比较熟悉,可能会更容易理解一些。
当然了,网易云接口还有好多好玩儿的东西,具体请参照小五哥之前的微信公众号文章《收藏这些API,获取网易云音乐数据超轻松》。
大家可以看看其他的网易云音乐的接口介绍,很有意思,不过爬取的数量是有限制的,但是练练手总是足够的。
- 2、关于requests库
这是爬虫的基本库之一,用我们英语老师的话讲:不要问原因,这是固定搭配,背下来即可。
requests.get(url,headers=headers)
主要是用来将网页的源代码给提取出来。
data = json.loads(response.text) comments = json_normalize(data['comments']) wangyimusic_comments=comments.append(wangyimusic_comments) print('抓取完第{}页'.format(str(i//100))) time.sleep(np.random.randint(2, 7))
通过接口抓取数据我不知道有没有速度的限制,但是我们在抓取正常网站数据时还是不要太过分。孔子曰:以和为贵,所以每次请求我就间隔了随机的2~7秒的时间。
wangyimusic_comments.to_csv('hot_wangyimusict.csv',encoding='utf-8-sig',index=False)
关于json_normalize,这是我目前遇到的解析json为DataFrame格式最简单的方式了(当然,也可能是我头发长见识短的原因)。
json_normalize(data['comments']) 直接将数据转化为DataFrame格式了,这种方式我是一见钟情。
毕竟简洁是一种美,而且是一种大美。
关于写入数据pd.to_csv 其实这里没有必要存入文件,因为我们可以直接保存在变量里,直接在下面的语法中调用即可。
但是我想说的最重要的,几乎每个人在爬取数据保存数据时都会遇到的报错:
打开文件乱码,这里使用encoding='utf-8-sig',这样就解决了写入文件乱码的异常,具体的原理为什么encoding='utf-8'不行,而encoding='utf-8-sig'就可以了。
大家可以查阅CSDN文章《Python 读取文件首行多了"ufeff"字符串》,解释的很通俗。我想说的次重要的,是index=False,如果不加这个参数,会导致DataFrame写入文件带有默认的index 1 2 3 ...
这个没有意义的index,至少我是不想写入文件保存下来的,因此直接去掉。
text = ''commts = wangyimusic_comments.contentfor commt in commts: text += ' '.join(jieba.lcut(commt))
曾经的jieba的安装让我头疼,但是不知道为何,我直接在annaconda里pip install jieba就直接成功了。
jieba.lcut是对每个评论进行分词处理,通过join函数将分词合成一个字符串。
background_image = np.array(Image.open(r'C:UsersjiangmsPictures640.png'))
读取图片文件我一开始用的是,
import matplotlib.pyplot as pltplt.imread(img)
但是却报了如下的错:
UserWarning: mask image should be unsigned byte between 0 and 255
翻译成人话:图片可以展现,问题是没有导入图形的轮廓,而且出现了警告,意思是:掩码图像应为0到255之间的无符号字节,所以要将图片转为数组。
使用np.array(Image.open(img)),即可避免报错信息,但是W H Y ??真的不了解 。
为什么要用二值化图片,原理并不清楚,之前学PS的时候也是在三原色,通道那儿糊涂着。
wc = wordcloud.WordCloud( font_path='C:/Windows/Fonts/SimHei.ttf', #设置字体,解决显示口字型乱码问题 mask=background_image, #图片背景 # width=1200, #图片宽度 # height=900, #图片高度 max_words=1000, #最大词数 max_font_size=150, # 最大字体大小 min_font_size=4, # 最小字体大小 scale=1.5 #)
需要说明的是如果参数mask存在的话,那么高度和宽度参数将会失效,这个需要注意一下。
wc.generate(text)plt.imshow(wc)plt.show()#使用matplotlib进行显示wc.to_file('wordcloud.jpg')#保存图片
好了,文章到了这儿就结束了,有几个注意点希望能给大家提醒,能给大家启发。
- 华为面试题——一道关于指针方面的编程题(C/C++)
- Spring Cloud第二篇 创建一个Eureka Server
- 数据挖掘实战(一):Kaggle竞赛经典案例剖析
- 华为面试题——单向链表倒转(一次遍历)
- Flask一步步搭建web应用
- (44) 剖析TreeSet / 计算机程序的思维逻辑
- (46) 剖析PriorityQueue / 计算机程序的思维逻辑
- (48) 剖析ArrayDeque / 计算机程序的思维逻辑
- 那些年在win下填过的Django坑
- Python爬虫一步步抓取房产信息
- (47) 堆和PriorityQueue的应用 / 计算机程序的思维逻辑
- 一篇文章完全理解virtualenv
- Python运用蒙特卡洛算法模拟植物生长
- (57) 二进制文件和字节流 / 计算机程序的思维逻辑
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 学习|C#线程中AutoResetEvent的使用
- Httprouter—用go实现的高性能路由器
- Django-python最流行的web框架
- C++ 类的不同构造与三种引用
- C++继承、虚函数、RTTI、友元类、异常处理
- C++基本语法
- 抓包分析TCP三次握手四次挥手全过程,教你观看“多包运动”的正确姿势
- 抓包分析以太网帧和IP数据包,头部那么多东东用来干啥的,扫盲篇
- 一文洞悉 OSI和TCP/IP模型,理通所有协议,再也不用似懂非懂了
- 图解https演变以及各种加密解密过程一篇就够!(通俗易懂白话文)
- vs code 创建vue模版
- WebAssembly如何演进成为“浏览器第二编程语言”?
- SAP ABAP和Java的动态代理实现
- SAP ABAP CGLIB(Code Generation Library)的模拟实现
- 如何监听SAP CRM BOR事件