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分析弹幕接口

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。

对课程的建议

  • 感觉爬虫那节课的课后作业很不错,可以多添加一些这种课后实践的小作业,但考虑到大家学习压力比较大,可以适当删减一次实验?改为平时的实践?(不成熟的想法)

参考链接

posted @ 2022-05-29 09:22  20211308wjc  阅读(42)  评论(0编辑  收藏  举报