20211308 武久淳 实验四 Python综合实践
20211308 2021-2022-2《python程序设计》 实验四 Python综合实践
项目实践名称:爬取B站谷爱凌的弹幕并情感分析生成词云图
项目要求:
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)
注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
批阅:注意本次实验不算做实验总分,前三个实验每个实验10分,累计30分。本次实践算入综合实践,打分为25分。
评分标准:
(1)程序能运行,功能丰富。(需求提交源代码,并建议录制程序运行的视频)10分
(2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。10分。
(3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。5分
(4)如果没有使用华为云服务(ECS或者MindSpore均可),本次实践扣10分。
实验分析及设计过程
1.爬虫部分
1.1分析弹幕接口
- 经过上网搜寻:得知B站已经给予了获取弹幕的接口,只需要知道相应的cid号即可爬取相应弹幕。
- 接口如下:http://comment.bilibili.com/{cid}.xml
- 或者:https://api.bilibili.com/x/v1/dm/list.so?oid=
1.2如何获取cid号
- 在浏览器中点击F12进入开发者页面,切换到网络->XHR->负载->查询cid
如图:以https://www.bilibili.com/video/BV1e341177ES?spm_id_from=333.337.search-card.all.click为例
- 找到了cid后,把接口中的cid填入,即可对所有弹幕进行爬取。
2.1爬虫代码部分
2.11所要用到的库
库的名称 | 库的作用 |
---|---|
re | 提取正则表达式 |
requests | 发送爬虫请求 |
bs4 | 生成爬虫解析界面 |
time | 控制时间的库 |
panda | 数据处理库 |
os | 控制路径强大的库 |
2.2思考代码过程
- 用get方法向视频地址发出请求,利用正则提取出html文档中的cid号
r1 = requests.get(url=v_url, headers=headers)
html1 = r1.text
cid = re.findall('cid=(.*?)&aid=', html1)[0] # 获取视频对应的cid号
print('该视频的cid是:', cid)
- 根据正则提取出的cid号,补全xml的接口地址,再次发送请求。
danmu_url = 'http://comment.bilibili.com/{}.xml'.format(cid) #补全弹幕地址
print('弹幕地址是:', danmu_url)
r2 = requests.get(danmu_url)
- 解析xml页面
由于对HTML和xml不太熟悉,上网自学后了解到标签的文本内容为弹幕, 标签内p属性值的第四个字段是时间戳,然后分别用.find_all方法爬取视频地址,弹幕地址,弹幕时间,弹幕内容
初此之外还要记得转换时间格式
参考链接:https://blog.csdn.net/weixin_46235428/article/details/113859077
soup = BS(html2, 'xml')
danmu_list = soup.find_all('d')
print('共爬取到{}条弹幕'.format(len(danmu_list)))
video_url_list = [] # 视频地址
danmu_url_list = [] # 弹幕地址
time_list = [] # 弹幕时间
text_list = [] # 弹幕内容
for d in danmu_list:
data_split = d['p'].split(',') # 按逗号分隔
temp_time = time.localtime(int(data_split[4])) # 转换时间格式
danmu_time = time.strftime("%Y-%m-%d %H:%M:%S", temp_time)
video_url_list.append(v_url)
danmu_url_list.append(danmu_url)
time_list.append(danmu_time)
text_list.append(d.text)
print('{}:{}'.format(danmu_time, d.text))
- 将爬取到的数据保存到csv文件中,并避免重复出现表头
df = pd.DataFrame() # 初始化一个DataFrame对象
df['视频地址'] = video_url_list
df['弹幕地址'] = danmu_url_list
df['弹幕时间'] = time_list
df['弹幕内容'] = text_list
if os.path.exists(v_result_file): # 如果文件存在,不需写入字段标题
header = None
else: # 如果文件不存在,说明是第一次新建文件,需写入字段标题
header = ['视频地址', '弹幕地址', '弹幕时间', '弹幕内容']
df.to_csv(v_result_file, encoding='utf_8_sig', mode='a+', index=False, header=header) # 数据保存到csv文件
- 调用主函数,将想爬取的视频BV号写入,并写好保存路径
if __name__ == "__main__":
print('爬虫程序开始执行!')
# 保存数据的文件名
csv_file = '谷爱凌b站弹幕b.csv'
# 如果存在csv文件,先删除,避免数据重复
if os.path.exists(csv_file):
print('{}已存在,开始删除文件'.format(csv_file))
os.remove(csv_file)
print('{}已删除文件'.format(csv_file))
bv_list = ['BV1hY4y1i7TZ', 'BV1hu411v7rY', 'BV1Np4y1B79t', 'BV1n64y1D7zT', 'BV1gR4y1777Q']
# 开始爬取
for bv in bv_list:
get_bilibili_danmu(v_url='https://www.bilibili.com/video/{}'.format(bv), v_result_file='谷爱凌b站弹幕.csv')
print('爬虫程序执行完毕!')
利用PUTTY连接华为ECS服务器,运行代码截图
在保存路径中找到esv文件
2.2情感分析+词云
库的名称 | 库的作用 |
---|---|
pandas | 数据分析库 |
wordcloud | 词云库 |
PIL | 读取照片 |
numpy | 将照片读取为矩阵 |
2.21分析过程
- 上网学习SnowNLP给爬取到的内容自动进行打分,并统计占比情况(自己设置积极、消极的分数段,这里设置小于0.3就为消极)
- 这里打分的原理基本为将内容转换为矩阵,对矩阵中的数据进行统计
- 用wordCLoud制作词云图
2.22代码实现思路
- 引入所需要的库
import pandas as pd
from snownlp import SnowNLP
from pprint import pprint
import jieba.analyse
from PIL import Image
import numpy as np
from wordcloud import WordCloud
- 设置情感分析函数,用snowNLP方法遍历每个每个值,如果小于0.3则计算为消极,否则则是积极,最后输出结果。
def sen_analyse(v_cmt_list):
score_list = [] # 情感评分值
tag_list = [] # 打标分类结果
pos_count = 0 # 计数器-积极
neg_count = 0 # 计数器-消极
for comment in v_cmt_list:
tag = ''
sentiments_score = SnowNLP(comment).sentiments
if sentiments_score < 0.3:
tag = '消极'
neg_count += 1
else:
tag = '积极'
pos_count += 1
score_list.append(sentiments_score) # 得分值
tag_list.append(tag) # 判定结果
print('negative rate:', round(pos_count / (pos_count + neg_count), 4))
print('positive rate', round(neg_count / (pos_count + neg_count), 4))
df['emotion score'] = score_list
df['analysis result'] = tag_list
df.to_excel('谷爱凌_情感评分结果.xlsx', index=None)
print('情感分析结果已生成:谷爱凌_情感评分结果.xlsx')
- 生成词云图函数
设置词云的基本参数,读取选用的背景图片
def make_wordcloud(v_str, v_stopwords, v_outfile):
print('开始生成词云图:{}'.format(v_outfile))
try:
stopwords = v_stopwords # 停用词
backgroud_Image = np.array(Image.open('谷爱凌照片.webp')) # 读取背景图片
wc = WordCloud(
background_color="white", #设置颜色
width=1500, # 宽度
height=1200, # 高度
max_words=1000, # 字数
font_path="C:\WINDOWS\FONTS\SIMSUN.TTC", #字体(自带的宋体)
stopwords=stopwords,# 停用词
mask=backgroud_Image, # 背景图片
)
- 利用jieba库里jieba.lcut方法分词
jieba_text = " ".join(jieba.lcut(v_str)) # 分词
wc.generate_from_text(jieba_text) # 生成词云图
wc.to_file(v_outfile) # 保存图片文件
print('词云文件保存成功:{}'.format(v_outfile))
except Exception as e:
print('make_wordcloud except: {}'.format(str(e)))
- 调用主函数
if __name__ == '__main__':
df = pd.read_csv('谷爱凌弹幕.csv') # 读取excel
v_cmt_list = df['弹幕内容'].values.tolist() # 评论内容列表
print('length of v_cmt_list is:{}'.format(len(v_cmt_list)))
v_cmt_list = [str(i) for i in v_cmt_list] # 将列表中所有元素转换成字符串
v_cmt_str = ' '.join(str(i) for i in v_cmt_list) # 将评论内容转换为字符串
sen_analyse(v_cmt_list=v_cmt_list)
keywords_top10 = jieba.analyse.extract_tags(v_cmt_str, withWeight=True, topK=10)
print('top10关键词及权重:')
print(keywords_top10)
make_wordcloud(v_str=v_cmt_str,
v_stopwords=['的', '啊', '她', '是', '了'], # 设置停用词
v_outfile='谷爱凌弹幕_词云图.jpg'
)
运行代码截图
- 在ECS上运行
- 在pycharm运行
- 查看保存的文件
- 生成词云图
遇到的问题及解决办法
1.关于如何爬取b站弹幕?
一开始的设想是通过request方法通过url爬取html文件,通过正则表达来获得弹幕,但方法有些麻烦,得到的json文件不好解码。
于是看到了下面这个链接,发现通过cid然后进行拼接就可以爬取弹幕。
参考链接:https://www.jianshu.com/p/d99a7f1097d3
2.用BeautifulSoup解析html文件时遇到下述报错
解决办法:下载lxml库,或者更换文件类型
3.ECS服务器默认python2.7,pip也同理无法安装库。
解决方法:在王老师发的资源里面寻找Linux下下载python3的方法,更新pip使得pip满足python版本。
4.wordcloud库安装不成功
直接pip install wordcloud下载不成功,上网寻找资料发现可以下载wheel文件,将文件保存到python的文件路径下,pip 安装wheel后,再用pip install wheel文件即可。
5.wordcloud出现不了中文
将字体改为中文字体,我这里用的是自带的宋体。
6.除此之外即使按照教程学习,但也会出现很多问题,比如前后变量名称不一致,报错不计其数,但面对这种问题只能细心了挨个挑问题了。
源代码和运行结果以及视频以打包发送给课代表。
本学期所学内容
- 变量赋值
- 运算符及其优先级
- 基本数据类型
- 循环语句
- 列表、元组、字典、集合
- 字符串与正则表达式
- 函数
- 面向对象程序设计
- 文件操作及异常处理
- Python操作数据库
- Python爬虫
对于python的理解
- 面向对象编程:Python既是面向对象的编程,也是面向对象编程,与其他主要的语言如:Java对比来说,Python是以一种简单的方式来实现面向对象的编程。
- 可移植性强:Python可以被移植在许多的平台上,比如说Lnux、FreeBSD等
- 解释性:Python语言写的程序不需要编译成为二进制的代码,可以直接从源代码运行程序。
- 可扩展性强:某些算法不公开,这个部分的程序可以选择用C语言进行编写,然后再Python程序中进行使用。
- 具有丰富的库:Python具有丰富强大的标准库,包含了正则表达式re、线程thread、数据库pandans、OpenCV等,可以从都这些库中调用方法,Python语言功能十分强大。
详细知识点
自己写了一个总结博客:
课程感悟
上学期在信息安全专业导论中就浅浅学习过python,但也只是停留在基本的语法层面,想多学习一些python应用方面的问题,于是就报名了python程序设计这门课,经过一学期的学习,对于python的应用有了些许的了解
老师给的学习资料很丰富,可以根据自己所希望学的内容进行自主学习。
经过学习python程序设计这门课,我渐渐地发现终身学习的重要性,如何做到不断学习,不断地遇到新的问题不断地解决问题,通过查询资料,了解了代码原理,学会将学会的技能运用到自己的代码中,这是一个很综合的能力,以我自己来说,编程最吸引我的就是运行结果成功的那一刻,但想达到那一刻会付出很多的努力,但我认为这也是学习的意义所在吧。
当我们每一次发现作业不会做,我们是否仍然记得学期初的初心?是否有耐心静下心钻研?没有动力就拖延下去,等到“第一生产力”ddl的到来,但当你真正的解决这个问题后,你会发现:只有做好一个个小事,才能做好一件件大事。
用一句话总结:热爱真的会让一个人走的很远,人生苦短,我用python。
对课程的建议
- 感觉爬虫那节课的课后作业很不错,可以多添加一些这种课后实践的小作业,但考虑到大家学习压力比较大,可以适当删减一次实验?改为平时的实践?(不成熟的想法)