利用python爬取豆瓣电影的影评生成词云
本文代码开发环境为Jupyter,python version 3.7。
首先导入要用到python中所有的包
from urllib import request
from bs4 import BeautifulSoup as bs
import urllib.request
import re
import pandas as pd
import numpy as np
import jieba
import wordcloud
from wordcloud import WordCloud
import matplotlib
import matplotlib.pyplot as plt
import warnings # 防止出现future warning
warnings.filterwarnings("ignore")
获取电影列表
打开豆瓣网,查看豆瓣网的源代码,找到正在热映片源的板块。识别的ID为nowplaying。可以看到,目前正在上映的只有叶问4。
开始爬取豆瓣网页的信息,爬取的正在上映的电影信息。为了防止爬虫触发豆瓣的反爬虫机制,需要用浏览器用户代理的信息伪装一下,可以通过浏览器中输入chrome://version/查看代理信息。
将正在上映板块中的代码全部获取下来。这些代码中包括了电影的信息:名称、主演、时长等等....
url = "https://movie.douban.com/cinema/nowplaying/guangzhou/"
#伪装网页浏览器
headers = ("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
html_data = opener.open(url).read().decode('utf-8')
soup = bs(html_data, 'html.parser') # 解析
nowplaying = soup.find_all('div', id='nowplaying') # 网页中id为nowplaying是现在正在上映的电影。
nowplaying_list = nowplaying[0].find_all('li', class_='list-item') # 寻找所有上映电影相关信息
nowplaying_list
分析代码信息获取电影列表
分析获取到的代码信息,分析电影的ID和名称
movie_list = [] # 获取电影id和电影名
for item in nowplaying_list:
movie_dic = {}
movie_dic['id'] = item['id']
movie_dic['name'] = item['data-title']
movie_list.append(movie_dic)
获取电影评论信息
打开豆瓣网的评论网页,和获取电影的列表一样,查看源代码的信息,将所有评论板块的代码信息爬取下来。与获取电影页面相同,为了防止触发豆瓣的反爬虫机制,需要用浏览器的代理信息对爬虫进行伪装。
url_comment = 'https://movie.douban.com/subject/' + movie_list[0]['id'] + '/comments?status=P'
html_comment = opener.open(url_comment).read().decode('utf-8')
soup_comment = bs(html_comment, 'html.parser')
comment_list = soup_comment.find_all('div', class_='comment')
分析代码获取影评
'''get comment list'''
comments = []
for item in comment_list:
comment = item.find_all('p')[0].span.string
comments.append(comment)
这个时候可以看到,关于电影的影评已经被我们从网页上全部收集下来并存放在一个列表中。接下来需要获取到的评论信息进行数据清洗的处理。
数据清理
对于评论的清洗分为三步:
1.通过jieba将所有评论的句子拆分,去掉标点符号,提取出词组,存放在列表中。
'''clean comments'''
allComment = ''
for item in comments:
allComment = allComment + item.strip()
# 至少匹配一个汉字,两个unicode值正好是Unicode表中的汉字的头和尾。
pattern = re.compile(r'[\u4e00-\u9fa5]+')
finalComment = ''.join(re.findall(pattern, allComment))
segment = jieba.lcut(finalComment)
segment
2.统计分组,去除停用词
words_df = pd.DataFrame({'segment': segment})
stopwords = pd.read_csv(".....\stopwords.txt", index_col=False, quoting=3, sep="\t",
names=['stopword'], encoding='GBK')
words_df = words_df[~words_df.segment.isin(stopwords.stopword)]
".....\stopwords.txt"为定义的停用词文档,例如:“一个”,“一些”......百度下载TXT文档,停用词越多,识别出来需要的数据集会越准确。
3.数据统计
words_fre = words_df.groupby(by='segment')['segment'].agg({'count': np.size})
words_fre = words_fre.reset_index().sort_values(by='count', ascending=False)
对筛选出来有代表性的词语进行统计,排列出评论中每个词语出现的次数,在生成词云的时候选择频率高的词语。
生成词云
'''use wordcloud'''
matplotlib.rcParams['figure.figsize'] = [10.0, 5.0]
wordcloud = WordCloud(font_path='D:\python3.7\Movie\simhei.ttf', background_color='white', max_font_size=80)
word_fre_dic = {x[0]: x[1] for x in words_fre.values}
wordcloud = wordcloud.fit_words(word_fre_dic)
plt.imshow(wordcloud)
plt.show()