Python爬取老友记豆瓣评论生成词云

2017-11-10  本文已影响252人  34a03db0db07

不想老是忙着忙着被作业、杂事拖着走,所以最近打算每周做一个喜欢的small task,取悦自己。

第一个想到的是老友记,十月初看完老友记,非常喜欢,然后开始了速度缓慢的二刷。任务呢就是爬下豆瓣老友记的短评,做一个词云。

我的专业会接触到编程,于是课后学了一点点python入门,只懂得一些基本语法和数据结构,有时候闲着会写点脚本。所以对我来说,完成这个任务是一个学习的过程。

我主要参考了三篇文章:

  1. 我用Python爬了12万条影评,告诉你《战狼》都在说些啥
  2. Python正则表达式指南
  3. Python词云 wordcloud 十五分钟入门与进阶

思路简单讲就是一页一页的爬,用jieba将评论分词,最后用wordcloud做词云。
具体一些:

  1. 用requests库来爬取网页,所以需要自己的User-Agent和cookies。浏览器里打开短评页面登陆自己的账号,在审查元素模式下,刷新网页就能在network查看:


    查看自己的user-agent和cookies.png
  2. 分析评论页面url以及源代码,以编写正则表达式(Beautifulsoup也行)把页面中的评论取出来。页面中的评论全都在<p class="">后面,最开始我用beautifulsoup取评论出来,这样不太方便的是有的评论中带有图片等内容,使得<p>标签里夹有评论和其它标签,需要对这种情况做出判断并进一步处理。用正则表达式要好一些,遇到的困难是有的评论包含换行符,而.不能匹配换行符,然后尝试了[.\n],[\n.]后在网上找到了解决方法:[\s\S]能够匹配所有字符。
  3. 每页有20条评论,需要把下一页的链接取出来。比如老友记第一季的短评的第二页地址是:https://movie.douban.com/subject/1393859/comments?start=20&limit=20&sort=new_score&status=P&percent_type=,每次循环需要替换的是“start=20”这一部分。最开始我发现第一页start=0,第二页20,每次加20是有规律的,后来发现这样爬取的评论会重复。正确做法是每次都将页面中后页按钮下的链接取出来。
  4. 当爬取评论达到一定数量,几千或是过万后豆瓣会识别这是爬虫,便会禁止爬取,这时需要将未能爬取的网页输出,然后在浏览器中打开豆瓣输入验证码以证明自己不是爬虫,然后将代码中起始爬取url替换成刚刚输出的网址,这也是为什么打开txt文件使用‘a’追加模式的原因。这样就能一直爬取了,虽然需要点手动输入。


    输入验证码.png
  5. 本来我还想清洗一下评论,但在试用wordcloud的过程中发现wordcloud会自动去除数字、标点、特殊字符等,所以直接将分词后的结果给到wordcloud就行。
  6. wordcloud需要设置中文字体,也可以按照自己喜好设置图片遮罩(生成有形状的词云)。

下面是我的代码:
运行平台: python 3.6,mac Pycharm

#爬取评论
import requests
import re

comments_txt = open('txt文件的绝对路径', 'a')#'a'追加
head = {'your user-agent'}
cookies = {'cookie':'your cookie'}
url = 'https://movie.douban.com/subject/3286552/comments'
url_first = url + "?start=0"
html = requests.get(url_first, headers=head, cookies=cookies)
next_page = re.compile(r'<a href="(.*?)&amp;.*?class="next">') #下一页
r_comments = re.compile(r'<p class="">([\s\S]*?)<')#评论
rnum = 0 #计数

while html.status_code == 200:
    seg = ''
    for each in re.findall(r_comments,html.text):
        seg += (str(rnum+1) + '  '+ each.strip() + '\n')#strip去除首尾空白字符
        rnum += 1
    comments_txt.write(seg)
    url_next = url + re.findall(next_page, html.text)[0]
    html = requests.get(url_next, cookies=cookies, headers=head)
print(url_next)#接着这个起点爬
comments_txt.close()

#制作词云
import matplotlib.pyplot as plt
from wordcloud import WordCloud, STOPWORDS
import jieba

file = open('/Users/zeason/Desktop/friends-10.txt')
my_stopwords = open('评论txt文件的绝对路径')#去掉像‘这个’这样的词汇,这个停用词表网上都有
wordlist_after_jieba = jieba.cut(file.read())
wl_space_split = " ".join(wordlist_after_jieba)
stopwords = set(STOPWORDS)
for each in my_stopwords.readlines():
    stopwords.add(each.replace('\n',''))
my_wordcloud = WordCloud(stopwords=stopwords,background_color="white",width=5000, height=3000, margin=2,font_path = '中文字体的绝对路径').generate(wl_space_split)

plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()

我爬取了第一季和第十季的评论,词云如下:


第一季.png
第十季.png

最后,再表达一下我对老友记的喜欢吧~

上一篇下一篇

猜你喜欢

热点阅读