《战狼2》真心堪称中国的好莱坞大片,不管是打斗场景的展现,还是在特效的细节处理。吴京的那句“我只会花钱在武器上,花在取景上,永远不会花在小鲜肉上!”,也是近年来,观众对小鲜肉霸屏一种情怀的共鸣。基于对《战狼2》这么高热度的好奇,所以想爬取豆瓣电影上《战狼2》的评论,并做成词云,可视化展示观众对它的实际评论到底如何。核心流程分为3步:爬取评论,评论分词,绘制评论词云。
爬取豆瓣电影《战狼2》评论
在豆瓣电影上爬取点击了最高的10000个评论。豆瓣电影在不登录的情况下,只能查看前200条评论,登录后则没有这个限制,所以需要登录后才能完整的爬取10000条评论。如果直接使用模拟登录的方式,豆瓣在登录时是需要输入验证码的,使用模拟登录的方式难度较大,我们在这里直接使用标识已登录的cookie(dbcl2), 这个cookie的定位需要多次测试排除。核心代码如下:
def main():
session =requests.session()
# 手动粘取登录后的cookie信息,dbcl2对应的值。
cookies = {"dbcl2": ""}
for index in xrange(7000, 10000, 20):
# 爬取战狼评论
logger.info(u'爬取战狼第{}条评论'.format(index))
try:
response = session.get('https://movie.douban.com/subject/26363254/comments?start={}&limit=20&sort=new_score&status=P'.format(index), cookies=cookies)
if response.status_code != 200:
logger.error('failed, response status is {} not 200'.format(response.status_code))
break
else:
logger.info('success.')
except Exception as e:
logger.exception(e)
# 解析评论
selector = etree.HTML(response.content)
items = selector.xpath("//*[@id='comments']/div")
comments = []
for item in items:
try:
comment = item.xpath(".//*[@class='comment']/p/text()")[0].strip()
comments.append(comment)
except IndexError:
pass
# 保存到文件
file_path = os.path.join(BASE_DIR, "zhanlang_comments")
with open(file_path, 'a') as f:
for comment in comments:
f.write('{}\n'.format(comment))
sleep(5)
运行爬虫
评论分词
在这里选择了一个比较通用的中文分词词库jieba,调用它的textrank()函数对爬取的评论进行分词并归并。因为在绘制词云时需要关键词的频度(权值),所以设置wthWeight=True. 并设置MAX_WORDS = 500取出现频率最高的500个词组。
官方文档详见Github: jieba中文分词
from jieba import analyse
MAX_WORDS = 500
def get_words(path):
with open(path, 'r') as f:
content = f.read()
return analyse.textrank(content,topK=MAX_WORDS,withWeight=True)
绘制词云
绘制词云的方式很多,可以直接使用第三方工具如bluemc和一些库。这里使用功能强大的wordcloud,因为它不仅可以绘制出漂亮的词云,还可以自定义词云的背景。
选择一个喜爱的背景图片,最好与展示的主题相关。这里选择一个战狼2中出现比较高的武器:坦克
初始化设置wordcloud
- simsun.ttc字体(可以在网上下载喜欢的字体,并在程序中指定文件的路径);
- backgroud_color=”write”: 设置词云背景为白色,并通过mask参数设置背景形状;
- max_words=500: 设置词云中承载的词组最多为为500个;
def draw_wordcloud(words):
img_path = os.path.join(BASE_DIR, 'zhanlang.png')
font_path = os.path.join(BASE_DIR, 'simsun.ttc')
back_coloring = imread(img_path)
wordcloud = WordCloud(
font_path=font_path,
background_color="white",
max_words=MAX_WORDS,
mask=back_coloring,
max_font_size=80,
random_state=42
)
items = dict(words)
for item in items:
print item
wordcloud.generate_from_frequencies(dict(words))
wordcloud_img_path = os.path.join(BASE_DIR, 'zhanlang_word_cloud.png')
wordcloud.to_file(wordcloud_img_path)
绘制生成的词云如下: