透过这张词云,我看到了网友对性侵少女事件的愤怒
词云是一种非常炫酷而且实用的数据可视化方法:通过将关键词直接在图上展示,可以让读者直观的接受文本类的信息;同时,还可以通过字体的大小表示关键词的频率或热度,通过图片的形状来美化图片,呼应主题。
鉴于网上也可以搜到读取一整个文本绘制词云的教程,今天和大家分享一个更具实战性的案例:爬取网易新闻并绘制词云。另外,由于本人的代码洁癖,我称此方案为“最简实现”,只需替换url即可“无脑实现”。下面就让我们以最近讨论火热的《涉嫌性侵未成年女儿三年,揭开这位总裁父亲的“画皮”》这篇新闻的评论开始吧!
《涉嫌性侵未成年女儿三年,揭开这位总裁父亲的“画皮”》这篇新闻的评论 http://comment.tie.163.com/F9Q1252F05506O99.html
【1-确定评论接口】
页面上的评论都是通过请求数据接口来获得的,只要找到了数据接口就等于找到了数据。在评论页面上点击右键,选择【检查】选项,可以打开“开发者工具栏”。按照下图中1-4的顺序依次点击,即可在5处所指的位置看到获取评论数据的接口地址。
【2-爬取数据】
将评论接口地址中"offset="后面的部分替换为"{}"并赋值给url变量,运行下方的代码即可实现评论的爬取。其中具体的接口解析方法可以参考我之前的原创文章《Python对JSON格式数据的解析(以疫情数据为例)》。
# 导入依赖模块
import json
import requests
import pandas as pd
from pandas.io.json import json_normalize
# 设置请求参数
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36'}
url="http://comment.api.163.com/api/v1/products/a2869674571f77b5a0867c3d71db5856/threads/F9Q1252F05506O99/comments/newList?ibc=newspc&limit=30&showLevelThreshold=72&headLimit=1&tailLimit=2&offset={}"
#评论爬取
df = pandas.DataFrame(None)
i = 0
while True:
ret = requests.get(url.format(str(i*30)), headers=headers)
text = ret.text
result = json.loads(text)
t = result['comments'].values()
s = json_normalize(t)
i += 1
if len(s) == 0:
print("爬取结束")
break
else:
df = df.append(s)
print("第{}页爬取完毕".format(i))
# 评论去重(回帖有重复)
df=df.drop_duplicates('commentId').reset_index(drop=True)
【3-绘制词云】
运行下面的代码即可绘制词云,其中有两个地方要详细说明一下:
1是对dataframe中的评论列进行批量分词时,用到了一个双重的“列表推导式”,这个后面我会单独写一篇文章来介绍。
2是由于Python画图时默认的字体不支持中文显示,所以需要约定下字体的路径,下面代码中写的是windows系统中的字体路径,Mac系统中的字体路径可以参考下面这篇文章。另外也可以下载自己喜欢的字体。
Mac OS X:字体位置及其目的 https://support.apple.com/zh-cn/HT201722
# 导入依赖模块
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# 文本分词
word = [
y
for x in df.content.tolist()
for y in list(jieba.cut(x, cut_all=True))
]
# 设置词云图层属性,字体、长宽等
wd=WordCloud(font_path='C:/windows/fonts/simhei.ttf')
# 输入要绘制的文本
wd=wd.generate(" ".join(word))
# 绘制词云
plt.imshow(wd)
# 隐藏坐标轴
plt.axis('off')
# 画图
plt.show()
运行代码即可得到评论的词云如上图所示,我们可以看到图片上“一个”、“这个”、“不是”、“就是”等几个最大的词语并不能反映出评论的有效信息,这就需要我们使用stopword参数来设置停用词,代码如下:
# 设置停用词
stopword = ['一个','这个','不是','就是','没有','什么','这样','这种','怎么']
wd = WordCloud(font_path='C:/windows/fonts/simhei.ttf', stopwords=stopword, width=1000, height=500)
wd = wd.generate(" ".join(word))
plt.imshow(wd)
plt.axis('off')
plt.show()
运行上面的代码得到新的词云,可以从图上“禽兽”、“人渣”、“畜生”、“变态”、“枪毙”这些关键词清晰的看到网友们的愤怒。
【4-总结与拓展】
今天介绍了爬取网易新闻的评论并绘制词云的方法,主要可以分为以下几步:确定评论接口、爬取数据、评论分词、绘制词云。
对于词云的优化,除了控制停用词外还有很多可以调整的地方。比如通过WordCloud函数中的color_func参数控制文字的颜色、通过background_color参数控制背景颜色、通过mask参数控制词云的形状等等,大家可以自己尝试,如果遇到困难可以在公众号中回复交流。