人不在江湖,江湖已满是传说
……早些天,周某还未出狱,其即将于4.18出狱已登上热搜;而4.18日,有关他出狱的消息并未比上次火爆。周某关于柳州某监狱,博主也是柳州人,在这一代年轻人的圈子里,当然多多少少会关注一些。据圈里知情,和其他出狱者不同,他已经是政府机关的重点关注对象,一大早就被南宁机关专车接走,还没能露面。
……在如今流量即为核心竞争力的网络影视、直播平台,自然会对这样一个网红开展突击行动。作为因入狱时的雷人三观而火起来的周某,劳改四年后还可以不可以直播成为热议焦点。接下来直接看一篇主要微博吧。
(由于出狱未能露面,微博热度没有想象的那么高;而在直击热度的媒体中,成都商报的这篇文章成为了热议主体,评论达四万多,其他相关微博也就一两千,并且有趣的是,成都商报的微博一般最多也就几百条评论,如今靠这篇推文一举远甩之前的评论量)
切入正题,以下是爬取这篇微博的评论以及文本分析的过程和python代码
首先导入所需要的库:
# coding=utf-8
import requests # 爬虫主要工具
import time # 计时器
import random # 随机数模块
import jieba # jieba分词模块
from wordcloud import WordCloud,STOPWORDS # 词云模块
import matplotlib.pyplot as plt # 绘图模块
from snownlp import SnowNLP # 自然语言处理模块
1、爬取评论python代码:
(这里我直接利用上次爬取微博评论的代码,改了微博id即可,详细教程可参考我上一篇文章:
简单爬取微博评论详细解析,学习爬取ajax异步数据交换动态网页
start = time.time() # 开始计时
user_agents = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60',
'Opera/8.0 (Windows NT 5.1; U; en)',
'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 ',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0) ',
] # 我在网上搜来的很多网页的引擎
f = open('qiegewala.txt', 'w',encoding='utf-8')
def GET_COMMENT(id):
usedid=[0]
max_id = 0
max_id_type = 0 # 开始的链接一般这两个值都是0
BOOL = 0 # 用于判断是否爬取结束的标识
url = 'https://m.weibo.cn/comments/hotflow?id={}&mid={}'.format(id,id) # 刚开始第一个链接
while 1:
# 爬完一个 暂停2秒
headers = {
'Cookie':'your cookie',
'SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5RJaVYrb.BEuOvUQ8Ca2OO5JpX5K-hUgL.FoqESh'
'-7eKzpShM2dJLoIp7LxKML1KBLBKnLxKqL1hnLBoMceoBfeh2EeKBN; '
'SCF=AnRSOFp6QbWzfH1BqL4HB8my8eWNC5C33KhDq4Ko43RUIzs6rjJC49kIvz5_RcOJV2pVAQKvK2UbAd1Uh6j0pyo.; '
'SUB=_2A25zQaQBDeRhGeBM71cR8SzNzzuIHXVQzcxJrDV6PUJbktAKLXD-kW1NRPYJXhsrLRnku_WvhsXi81eY0FM2oTtt'
'; SUHB=0mxU9Kb_Ce6s6S; SSOLoginState=1581634641; WEIBOCN_FROM=1110106030; XSRF-TOKEN=dc7c27; '
'M_WEIBOCN_PARAMS=oid%3D4471980021481431%26luicode%3D20000061%26lfid%3D4471980021481431'
'%26uicode%3D20000061%26fid%3D4471980021481431',
'User-Agent': random.choice(user_agents), # 我从池里随便选一个,躲避反爬
'X-Requested-With': 'XMLHttpRequest'}
proxies = {'http': 'http://218.21.96.128:58080'} # 我为了反爬用了个免费代理 (可以不用,没用的话不用待会参数别写就行)}
pars = {
'max_id': max_id,
'max_id_type': max_id_type
} # 记录爬取页面的下一个链接的信息
response = requests.get(url, params=pars, headers=headers,proxies=proxies) # 对链接发送请求
# response 是链接的内容,和在网页打开的一样
try: # 避免网页内容可能出错 我用了try 继续往下
for json in response.json()['data']['data']: # 按照刚才的搜索路径找到JSON字典里面的子字典和列表
comment = json['text'] # 读取 评论内容
comment = comment.split('<')[0] # 有的评论内容后边有<>包裹的英文信息,将评论内容以 < 拆开 选取前面的一个就是想要的内容
f.write(comment + '\n') # 写入目标文件
# 类似的,下面找到跳转到下一条链接所需内容 max_id 和max_id_type
max_id = response.json()['data']['max_id']
max_id = int(max_id) # 可能是字符串,转为数字
max_id_type = response.json()['data']['max_id_type']
max_id_type = int(max_id_type)
print(max_id, max_id_type) # 可以打出来看看它们的变化
if max_id in usedid:
BOOL=1
usedid.append(max_id)
except: # 如果爬取出错,或者爬取完毕 将BOOL设置为1 跳出爬虫
BOOL = 1
if BOOL:
break
time.sleep(2)
GET_COMMENT(4495124471976051)
f.close()
end = time.time() # 设置结束时间
total = end - start # 求取总时间单位是秒
print("总用时", total / 60, '分钟')
……由于微博上显示的4.7万评论是包括每一条评论下面的回复评论的,而我爬取的评论只是直接的评论未包括评论下的回复评论,一共也就5000多条,因为评论下的回复评论实在太多了占了八成以上,比如光第一条评论下就有9000条回复评论了。
以下展示爬取结果,保存在命名未‘qiegewala.txt’的txt文件中:
2、文本分词处理:
……首先要介绍停用词,停用词就是那些语句中常带有的语气词、标点之类等没有语义的词语,例如:的,呢,呀 , 。 ! 。
待会分词的同时直接在程序里面去掉,不再解释
# coding:utf-8
import jieba
import matplotlib.pyplot as plt
# 导入评论
f1=open('qiegewala.txt','r',encoding='utf-8')
page=f1.readlines()
f1.close()
# 导入停用词集
f2=open('stopwords1.txt','r',encoding='gbk')
stopwords=f2.readlines()
f2.close()
# 分词前需要去掉换行符 '\n'
words=[]
for line in page:
words.append(line.strip('\n'))
stopword=[]
for sw in stopwords:
stopword.append(sw.strip('\n'))
#print(stopword)
word=jieba.lcut(str(words)) # 分词
#下面是计算词频 ,并给出 前50个最高频率的词语
word_tf={}
for w in word:
if w not in word_tf.keys():
word_tf[w]=1
else:
word_tf[w]+=1
# 去用词
for sw in stopword:
if sw in word_tf.keys():
word_tf.pop(sw)
word_tf.pop(' ')
#print(word_tf)
下面提取前50个高频词汇看一下:
代码:
# 将字典按照value即频率排序
Zip=zip(word_tf.values(),word_tf.keys())
order=list(Zip)
order.sort(reverse=True)
# 提取排序好的前50个词语 并作图
word_name=[]
word_num=[]
for i in range(50):
word_name.append(order[i][1])
word_num.append(order[i][0])
# 画出条形图
plt.figure(figsize=(13,5))
plt.bar(range(50),word_num)
plt.xticks(range(50),word_name,rotation=90)
plt.rcParams['font.sans-serif']=['SimHei'] # 坐标是中文 必须用这个函数
plt.savefig('qiegewala.jpg')
plt.show()
当然,也可以用分词好的文件做一个词云图,频率越高词汇越大,评论的热议大致内容一览无余(snownlp里也有一个停用词对象,直接可以在生成词云图的时候去掉停用词,不必像刚才一样手动除去停用词,我这里使用一下。不过两种停用词库是不一样的,去除的词也不一样)
可以从这些词汇得出什么信息,仁者见仁,智者见智呗。
代码:
wc = WordCloud(
font_path='simhei.ttf', # 字体
background_color="white", # 背景色
max_words=1000, # 最大词数
width=3000, # 输出宽度
stopwords=STOPWORDS, # 去停用词
height=3000,
)
wc.generate(word) # 转化为词云的操作
wc.to_file("qiegewalaciyun.jpg") # 保存
3、评论情感分析
对这5000条评论进行情感打分,打分在[-0.5,0.5]之间,大于0是积极、支持的,小于0是消极、反对的,越靠近边缘,情感越突出。
为了观看每个评分区间的数量,做一个频率直方图:
(这个打分关系到词集的训练问题,我用的是snownlp库中原来带有训练好的模型, 是不符合我这个新文本。如果要得到正确打分,必须要用自己的文本重新训练,准确的训练过程并不容易。我这里为了方便,直接调用原来训练好的模型作为输出结果,方法和代码可以参考,但结果一定是有较大的问题的,因为评论的语句很多是反讽。以后有机会会把情感分析深入研究再进一步评估。)
代码:
sentiment_list=[]
success=0
error=0
for line in word:
try:
s=SnowNLP(line)
ss=s.sentiments-0.5
sentiment_list.append(ss)
success +=1
print('success=', success)
except:
error+=1
fs=open('sentiment_list.txt','w',encoding='utf-8')
fs.write(str(sentiment_list))
fs.close()
plt.hist(sentiment_list)
plt.show()
需要文本资料的朋友可以私我邮箱