〇、前情提要
想随便先爬点什么看看,看到b站这个视频很短,就开搞这个。
参考:
- 【Python爬虫+本科毕业论文速成】豆瓣评论-我是余欢水-数据抓取-情感分析-评分统计-词云制作
https://www.bilibili.com/video/BV18C4y1H7mr?from=search&seid=1875460052043791117
为支持up已三连~代码请在三连后找他领取 - 豆瓣电影-我是余欢水 (2020)
https://movie.douban.com/subject/33442331/ - 【mac】在Safari里复制网页源代码、不可复制内容
https://blog.csdn.net/weixin_43210113/article/details/107442773 - CSV (逗号分隔值文件格式)
https://baike.baidu.com/item/CSV/10739?fr=aladdin - 揭开正则表达式的神秘面纱
http://www.regexlab.com/zh/regref.htm - Python—padas(DataFrame)的常用操作
https://www.jianshu.com/p/4ff1d2b23ab3 - pandas的to_csv()使用方法
https://blog.csdn.net/toshibahuai/article/details/79034829 - Python分词、情感分析工具——SnowNLP
https://www.cnblogs.com/zhuminghui/p/10953717.html
注意事项:
在代码执行时csv都需要为UTF-8格式,用excel打开时都需要为ANSI格式。
一、我是余欢水
豆瓣分长评和短评。
最初电视剧上映时好评多,后来因为某些争议被打一星。
有比较、有突变->适合学术、写论文
二、爬虫的结构
1. 网页地址的结构
我是余欢水 短评 https://movie.douban.com/subject/33442331/comments?start=0&limit=20&sort=new_score&status=P
- movie.douban.com 网址
- subject 下属菜单
- 33442331 我是余欢水在豆瓣电影中的id
- start=0 从第几条开始,前后页翻动则改变,循环增20
2. 评论的html结构
以此条评论为例,切成静态网页html
此处Safari不会操作的可以看我写的
【mac】在Safari里复制网页源代码、不可复制内容https://blog.csdn.net/weixin_43210113/article/details/107442773
<div class="comment-item" data-cid="2329338634">
<div class="avatar">
<a title="弗洛伊彪之怒" href="https://www.douban.com/people/121108591/">
<img src="https://img9.doubanio.com/icon/u121108591-56.jpg" class="">
</a>
</div>
<div class="comment">
<h3>
<span class="comment-vote">
<span class="votes">4098</span>
<input value="2329338634" type="hidden">
<a href="javascript:;" class="j a_show_login" onclick="">有用</a>
</span>
<span class="comment-info">
<a href="https://www.douban.com/people/121108591/" class="">弗洛伊彪之怒</a> //用户id
<span>看过</span>
<span class="allstar40 rating" title="推荐"></span> //用户评分
<span class="comment-time " title="2020-04-06 20:48:30">
2020-04-06 //用户评论时间
</span>
</span>
</h3>
<p class="">
<span class="short">太惨了太惨了,但是由于男主是郭京飞还是忍不住发出感慨:“好啊,苏明成你小子也有今天!请不要因为他是TF老boys而怜惜,鞭挞他吧” 。(脑内替余欢水自动播放bgm“百因必有果 明成的报应就是我”)</span> //评论内容
</p>
</div>
</div>
以上得到评论结构与循环代码,即可开始编程。
三、短评抓取-douban_movie_comment.py
1. 代码解释
import requests
import pandas as pd //存储文件使用pandas,然后转成csv文件
import re //正则表达式
import time
import csv
from bs4 import BeautifulSoup //网页解析
import os
from urllib import request //请求网址
CSV (逗号分隔值文件格式)
https://baike.baidu.com/item/CSV/10739?fr=aladdin
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。通常都是纯文本文件。建议使用WORDPAD或是记事本来开启,再则先另存新档后用EXCEL开启,也是方法之一。
cookies里的bid是自己豆瓣账号
每一页改变的量为start值,从0依次增20,url_1为start值的前缀,url_2为start值的后缀,需要后续拼接起来。
用try、except结构捕捉一些异常。
用request进行请求,得到一个响应。
用BeautifulSoup进行网页的解析。
抓取四个方面的内容:评论时间、评论用户名、评论文本、评分。
- 评论时间
<span class="comment-time " title="2020-04-06 20:48:30">2020-04-06</span>
soup.find_all(‘span’,attrs={‘class’:‘comment-time’})
寻找所有的类为comment-time的span
假设抓取了100页,当第100页的抓取到的评论时间数量为0时,将while停止,否则会无限循环下去。 - 评论用户名
<span class="comment-info"><a href="https://www.douban.com/people/121108591/" class="">弗洛伊彪之怒</a></span>
soup.find_all(‘span’,attrs={‘class’:‘comment-info’}).a.string
寻找所有的类为comment-info的span下的a标签里的内容 - 评论文本
<span class="short">太惨了太惨了,但是由于男主是郭京飞还是忍不住发出感慨:“好啊,苏明成你小子也有今天!请不要因为他是TF老boys而怜惜,鞭挞他吧” 。(脑内替余欢水自动播放bgm“百因必有果 明成的报应就是我”)</span>
soup.find_all(‘span’,attrs={‘class’:‘short’})
寻找所有的类为short的span - 评分
<span class="allstar40 rating" title="推荐"></span>
每个评分的class会不同,需要用正则表达式表示class里的内容。
soup.find_all(‘span’,attrs={‘class’:‘re.compile(r"allstar(\s\w+)?")’})
揭开正则表达式的神秘面纱
http://www.regexlab.com/zh/regref.htm
\s 包括空格、制表符、换页符等空白字符的其中任意一个
\w 任意一个字母或数字或下划线,也就是 AZ,az,0~9,_ 中任意一个
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
? 匹配表达式0次或者1次,相当于 {0,1},比如: "a[cd]?“可以匹配"a”,“ac”,“ad”
抓取到四个数值(均为列表)后,写一个循环(求列表长度,每一个数据是20个),将每页数据存入到data1列表中。
将列表用pandas转换为DataFrame格式,存储为douban_movie
Python—padas(DataFrame)的常用操作
https://www.jianshu.com/p/4ff1d2b23ab3
1、DataFrame是一种数据框结构,相当于是一个矩阵形式,单元格可以存放数值、字符串等,这和excel表很像;
2、DataFrame是有 行(index)和 列(columns)可以设置的;
创建(pd.DataFrame),to_csv()是DataFrame类的方法。
pandas的to_csv()使用方法
https://blog.csdn.net/toshibahuai/article/details/79034829
to_csv()是DataFrame类的方法。
- 路径 path_or_buf: A string path to the file to write or a StringIO
dt.to_csv(‘Result.csv’) #相对位置,保存在getwcd()获得的路径下- 是否保留列名 header: Whether to write out the column names (default True)
dt.to_csv(‘C:/Users/think/Desktop/Result.csv’,header=0) #不保存列名- 是否保留行索引 index: whether to write row (index) names (default True)
dt.to_csv(‘C:/Users/think/Desktop/Result1.csv’,index=0) #不保存行索引- mode
to_csv()方法mode默认为w,我们加上mode=‘a’,便可以追加写入数据。
每次循环结束i++。
每抓一页,休眠2s。
2. 执行结果
豆瓣短评只提供500条数据,抓到第25页后无权限,所以只显示25页,但也足够使用。
记事本打开,改成ANSI格式。
关闭后用excel打开。
查看完后将格式改回UTF-8,接下来对C评论文本进行情感分析,首先要得到情感分支。
四、情感分析-douban_sentiment_analysis.py
1. 代码解释
pd.read_csv(‘douban_movie.csv’,header=None,useclos=[2])
C列为第三列,序号为2。
将dataframe转换为列表形式。
显示评论有多少条,与后面情感分数长度保持一致,防止数据缺失。
用SnowNLP进行计算,并将评论的数值存储为sentiment.cav
Python分词、情感分析工具——SnowNLP
https://www.cnblogs.com/zhuminghui/p/10953717.html
- 安装
pip install snownlp- 导入SnowNLP库
from snownlp import SnowNLP- 需要操作的句子 text = ‘你站在桥上看风景,看风景的人在楼上看你。明月装饰了你的窗子,你装饰了别人的梦’
s = SnowNLP(text)- 分词
print(s.words)- 主要功能(请移步原链接查看)
中文分词(Character-Based Generative Model)
词性标注(TnT 3-gram 隐马)
情感分析(现在训练数据主要是买卖东西时的评价,所以对其他的一些可能效果不是很好,待解决)
文本分类(Naive Bayes)
转换成拼音(Trie树实现的最大匹配)
繁体转简体(Trie树实现的最大匹配)
提取文本关键词(TextRank算法)
提取文本摘要(TextRank算法)
tf,idf(信息衡量)
Tokenization(分割成句子)
文本相似(BM25)- 关于训练
现在提供训练的包括分词,词性标注,情感分析
from snownlp import seg
seg.train(‘data.txt’)
seg.save(‘seg.marshal’)
这样训练好的文件就存储为seg.marshal了,之后修改snownlp/seg/init.py里的data_path指向刚训练好的文件即可
2. 运行结果
500条评论,500条得分。
打开sentiment.cav文件,可得到所有情感得分。
并将A列数据复制粘贴到douban_mov.csvF列中。
添加标题列,方便统计。
time user recommend recommend title score
allstar10-50替换为1-5。(456一星 14二星 4三星 15四星 11五星)
替换完成后保存。
五、统计分析-douban_score_analysis.py
1. 代码解释
from collections import Counter 导入计数包
先读取文件,再统计每个评分的打分数量并显示。
按每个评分得出情感平均值。
2. 运行结果
与在【四】中的替换数量相同。
SnowNLP越倾向于1情感越正向,而此结果中1星得分比2星高,3星分值最高。
情感分析的结果是SnowNLP的锅,我们只需要知道代码实现即可。
六、词云制作-douban_wordcloud.py
1. 代码解释
import PIL.Image as Image
chinese_jieba在分词。
读取douban_movie.csv,读取comment和recommend两列。
做循环,当评分为1星时,将评分的文本分词。
调用PIL包方法制作词云。
找背景图片,设置字体等,设置停用词余欢水不显示。
2. 运行结果
字体越大,出现的频率越高。