最近在优酷看了杨洋和zs主演的某部青春爱情电视剧。所以想到观察一下它的评论,同时学习一下Python文本处理的基础知识。

首先第一部分就是获取评论数据。

优酷评论爬虫+词云图优酷评论爬虫+词云图

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函数。得到的图如下。

优酷评论爬虫+词云图

这里先存到列表,转到数据框,又存到列表,主要是考虑到直观性,可能不太高效,直接一步到位可能更加高效,占用内存更少。

由于爬虫需要一定的时间,而网页上的评论信息是实时更新的,所以数据可能会有些许的重叠。举个例子,刚爬取完第一页,将要爬取第二页时,有一位用户发表了一条新评论,则刚才第一页的最后一条评论就被顶到了第二页,在爬取第二页时会重复获取到这条数据。但是对于大规模的统计规律而言,这一误差并不重要。