优酷评论爬虫+词云图
最近在优酷看了杨洋和zs主演的某部青春爱情电视剧。所以想到观察一下它的评论,同时学习一下Python文本处理的基础知识。
1. 爬虫
首先第一部分就是获取评论数据。
import json import requests import pickle url = 'https://p.comments.youku.com/ycp/comment/pc/commentList?' payload = { 'jsoncallback': 'n_commentList', 'app': '100-DDwODVkv', 'objectId': 'XMTY5NDg2MzY5Ng==', 'objectType': '1', 'listType': '0', 'currentPage': '1', 'pageSize': '30', 'sign': 'edcc3e3b6c345339a426f93dbd9f05ca', 'time': '1553254978' } dataAll=[] for i in range(1,8001): print('Crawling page',i) payload['currentPage']=str(i) # 发起请求 try: response = requests.get(url, params=payload) text = response.text # 处理text text = text[16:-1] # 将str转换成字典 response_dict = json.loads(text) dataAll += response_dict['data']['comment'] except: pass if i%100==0: print('Saving data') f=open('test.pydata','wb') pickle.dump(dataAll,f) f.close()
https://p.comments.youku.com/ycp/comment/pc/commentList?是获取各种优酷评论的链接,这里需要添加payload才能获取到有限信息。XMTY5NDg2MzY5Ng==是代表视频的Id,在视频的链接中可以找到。
这里每页是30条评论,共计爬取了8000页,约24万条评论,并转换为字典,将信息保存在列表中。每隔100页向本地文件保存一次,防止程序意外崩溃数据丢失。这里用了pickle包,介绍见上一篇(https://www.cnblogs.com/dingdangsunny/p/14338032.html)。
其中一条即dataAll[0]的信息如下:
{'atUsers': {}, 'flags': {}, 'upCount': 0, 'parentCommentId': 0, 'userId': 1423248059, 'content': '荧屏从此再无小仙女!从这里开始喜欢,以后依然爱……', 'downCount': 0, 'replyCount': 0, 'createTime': 1612161835743, 'userIsLiked': 0, 'picList': [], 'parentComment': {}, 'id': 1000505895542, 'user': {'vipInfo': {'icon': 'https://gw.alicdn.com/tfs/TB1.SdDbRCw3KVjSZR0XXbcUpXa-48-48.png', 'mmid': 100002, 'name': '优酷土豆黄金会员', 'state': '1', 'icon2': 'https://gw.alicdn.com/tfs/TB15Tzer8r0gK0jSZFnXXbRRXXa-56-28.png', 'vipGrade': 4}, 'userLevel': 0, 'avatarMiddle': 'https://static.youku.com/lvip/img/avatar/50/20.png', 'avatarLarge': 'https://static.youku.com/lvip/img/avatar/310/20.png', 'userName': '我6128265256', 'userId': 1423248059, 'userCode': 'UNTY5Mjk5MjIzNg==', 'avatarSmall': 'https://static.youku.com/lvip/img/avatar/30/20.png'}}
之后可以通过以下代码重载数据。
import pickle f=open('test.pydata','rb') dataAll=pickle.load(f) f.close()
2. 词频统计
首先将评论文本整合到一个表格中。
import pandas as pd dfdata = pd.DataFrame(columns=['Id', 'comment']) for i in range(0,len(dataAll)): #for i in range(0,100): if i%100==0: print(i) dfdata = dfdata.append([{'Id': i, 'comment': dataAll[i]['content']}], ignore_index=True)
查看此时的数据:
# 查看数据 dfdata.head()
读取已经准备好的停用词表。
stopwords = pd.read_csv('stopwords.txt', encoding='utf-8', names=['stopword'], index_col=False) #stopwords.head() stop_list = stopwords['stopword'].tolist()
载入自定义的词典,并使用jieba进行分词。
import jieba jieba.load_userdict("dict.txt") dfdata['cut'] = dfdata['comment'].apply(lambda x : [i for i in jieba.cut(x) if i not in stop_list])
字典中可以放一些自定义的词,如电视剧中的人名等,否则可能不能被识别。
此时表格是这样的
将所有的词汇合并到列表中:
words = [] for content in dfdata['cut']: words.extend(content)
进行词频统计并输出前20名词汇:
# 导入相关库 from collections import Counter from pprint import pprint counter = Counter(words) # 打印前十高频词 pprint(counter.most_common(20))
保留前200高频词并生成字典用于绘制词云图。
c = counter.most_common(200) c_dic = {c[i][0]: c[i][1] for i in range(0,len(c))}
3. 词云图
from wordcloud import WordCloud # 使用WordCloud生成词云 word_cloud = WordCloud(font_path="simsun.ttc", # 设置词云字体 background_color="white") word_cloud.generate_from_frequencies(c_dic) # 运用matplotlib展现结果 import matplotlib.pyplot as plt plt.subplots(figsize=(12,8), dpi=300) plt.imshow(word_cloud) plt.axis("off") plt.savefig("wordcloud.jpg")
这里由于已经有了词频统计结果,所以直接使用了generate_from_frequencies函数。得到的图如下。
这里先存到列表,转到数据框,又存到列表,主要是考虑到直观性,可能不太高效,直接一步到位可能更加高效,占用内存更少。
由于爬虫需要一定的时间,而网页上的评论信息是实时更新的,所以数据可能会有些许的重叠。举个例子,刚爬取完第一页,将要爬取第二页时,有一位用户发表了一条新评论,则刚才第一页的最后一条评论就被顶到了第二页,在爬取第二页时会重复获取到这条数据。但是对于大规模的统计规律而言,这一误差并不重要。