不想老是忙着忙着被作业、杂事拖着走,所以最近打算每周做一个喜欢的small task,取悦自己。
第一个想到的是老友记,十月初看完老友记,非常喜欢,然后开始了速度缓慢的二刷。任务呢就是爬下豆瓣老友记的短评,做一个词云。
我的专业会接触到编程,于是课后学了一点点python入门,只懂得一些基本语法和数据结构,有时候闲着会写点脚本。所以对我来说,完成这个任务是一个学习的过程。
我主要参考了三篇文章:
思路简单讲就是一页一页的爬,用jieba将评论分词,最后用wordcloud做词云。
具体一些:
-
用requests库来爬取网页,所以需要自己的User-Agent和cookies。浏览器里打开短评页面登陆自己的账号,在审查元素模式下,刷新网页就能在network查看:
查看自己的user-agent和cookies.png - 分析评论页面url以及源代码,以编写正则表达式(Beautifulsoup也行)把页面中的评论取出来。页面中的评论全都在<p class="">后面,最开始我用beautifulsoup取评论出来,这样不太方便的是有的评论中带有图片等内容,使得<p>标签里夹有评论和其它标签,需要对这种情况做出判断并进一步处理。用正则表达式要好一些,遇到的困难是有的评论包含换行符,而.不能匹配换行符,然后尝试了[.\n],[\n.]后在网上找到了解决方法:[\s\S]能够匹配所有字符。
- 每页有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是有规律的,后来发现这样爬取的评论会重复。正确做法是每次都将页面中后页按钮下的链接取出来。
-
当爬取评论达到一定数量,几千或是过万后豆瓣会识别这是爬虫,便会禁止爬取,这时需要将未能爬取的网页输出,然后在浏览器中打开豆瓣输入验证码以证明自己不是爬虫,然后将代码中起始爬取url替换成刚刚输出的网址,这也是为什么打开txt文件使用‘a’追加模式的原因。这样就能一直爬取了,虽然需要点手动输入。
输入验证码.png - 本来我还想清洗一下评论,但在试用wordcloud的过程中发现wordcloud会自动去除数字、标点、特殊字符等,所以直接将分词后的结果给到wordcloud就行。
- 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="(.*?)&.*?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
最后,再表达一下我对老友记的喜欢吧~
网友评论