ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

20214302《Python程序设计》实验四 Python综合实践实验报告

2022-05-29 09:01:32  阅读:200  来源: 互联网

标签:文件 plt name Python html tag 实验报告 20214302 class


20214304《Python程序设计》实验四 Python综合实践实验报告

 

课程:《Python程序设计》
班级: 2143
姓名: 单宇航
学号: 20214302
实验教师:王志强
实验日期:2022年5月27日
必修/选修:公选课

 

一、实验内容

1.实验题目:

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)

注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2.实验内容:

爬虫+数据处理+可视化  

   利用爬虫爬取Bilibili动漫排行榜的信息并保存到本地txt文件中,将其中的相关数据存储到excel表格中(即动漫的名字、更新集数、播放量、收藏量),将其进行可视化处理,即制作出播放量与收藏量的柱状图和条形图进行比较和分析。

网址:https://www.bilibili.com/v/popular/rank/bangumi

 

 

 

 

二、实验过程及结果  

 

实验过程:

1.调用库:re, pandas, bs4(BeautifulSoup), matplotlib.pyplot, openpyxl

import re
import pandas
import requests
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
from matplotlib import font_manager

 

2.进行网页内容的爬取和保存

def main():
    url = 'https://www.bilibili.com/v/popular/rank/bangumi'  # 所要爬取的网址
    html = get_html(url)  # 获取返回值
    # print(html)
    info = save(html)   
    view(info)         # 重新调整张量维度,张量(Tensor)的目的是能够创造更高维度的矩阵、向量

def get_html(url):
    try:
        r = requests.get(url)  # 使用get来获取网页数据
        r.raise_for_status()  # 如果返回参数不为200,抛出异常
        r.encoding = r.apparent_encoding  # 获取网页编码方式
        return r.text  # 返回获取的内容
    except:
        return '错误'

# 解析网页
def save(html):
    soup = BeautifulSoup(html, 'html.parser')  # 指定Beautiful的解析器为“html.parser”

    with open('D:/爬虫测试/data1.txt', 'r+', encoding='UTF-8') as f:
        f.write(soup.text)  

 

 

3.将所需信息从爬取的内容中提取出来

 

    # 定义好相关列表准备存储相关信息
    name = []  # 动漫名字
    jsk = []   #集数库
    bfl = []  # 播放量
    scs = []  # 收藏数


    # ********************************************  动漫名字存储
    for tag in soup.find_all('div', class_='info'):
        # print(tag)
        bf = tag.a.string
        name.append(str(bf))
    print(name)

    # ********************************************  动漫集数
    for tag in soup.find_all('div', class_='detail'):
        # print(tag)
        js = tag.find('span', class_='data-box').get_text()
        js = re.search(r'\d*(\.)?\d', js).group()
        jsk.append(int(js))
    print(jsk)
    # ********************************************  动漫播放量
    for tag in soup.find_all('div', class_='detail-state'):
        # print(tag)
        bf = tag.find('span', class_='data-box').get_text()
        # 统一单位为‘万’
        if '亿' in bf:
            num = float(re.search(r'\d(.\d)?', bf).group()) * 10000
            # print(num)
            bf = num
        else:
            bf = re.search(r'\d*(\.)?\d', bf).group()
        bfl.append(float(bf))
    print(bfl)

    # ********************************************  收藏数
    for tag in soup.find_all('div', class_='detail-state'):
        sc = tag.find('span', class_='data-box').next_sibling.next_sibling.get_text()
        sc = re.search(r'\d*(\.)?\d', sc).group()
        scs.append(float(sc))
    print(scs)

#黄色部分下面内容会讲

 

4.将上述数据存入excel表格

    # 存储至excel表格中
    info = {'动漫名': name,'集数库': jsk, '播放量(万)': bfl, '收藏数(万)': scs}     
    dm_file = pandas.DataFrame(info)
    dm_file.to_excel('Data.xlsx', sheet_name="动漫数据分析")
    # 将所有列表返回
    return name, jsk, bfl, scs

 

5.制作柱状图和折线图


#使图上的数据可以显示中文
plt.rcParams['font.sans-serif'] = ['SimHei'] #运行配置参数中的字体(font)为黑体(SimHei)
plt.rcParams['axes.unicode_minus'] = False #运行配置参数总的轴(axes)正常显示正负号(minus)
# **********************************************************************播放量和收藏量数对比
# *******播放量条形图
fig, ax1 = plt.subplots()
plt.bar(dm_name, dm_play, color='cyan')
plt.title('播放量和收藏量数据分析')
plt.ylabel('播放量(万)')
ax1.tick_params(labelsize=6)
plt.xticks(rotation=90, color='green')

# *******收藏量折线图
ax2 = ax1.twinx() # 组合图必须加这个
ax2.plot(dm_favorite, color='green') # 设置线粗细,节点样式
plt.ylabel('收藏量(万)')
plt.plot(1, label='播放量', color="cyan", linewidth=5.0)
plt.plot(1, label='收藏量', color="green", linewidth=1.0, linestyle="-")
plt.legend()
plt.savefig(r'D:/爬虫测试/1.png', dpi=1000, bbox_inches='tight')

plt.show()

 

5.最后设置python程序的模拟入口,正确的入口对应出口

if __name__ == '__main__':
    main()

 

6.最终完整代码:

import re
import pandas
import requests
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
from matplotlib import font_manager


def get_html(url):
try:
r = requests.get(url) # 使用get来获取网页数据
r.raise_for_status() # 如果返回参数不为200,抛出异常
r.encoding = r.apparent_encoding # 获取网页编码方式
return r.text # 返回获取的内容
except:
return '错误'


def save(html):
# 解析网页
soup = BeautifulSoup(html, 'html.parser') # 指定Beautiful的解析器为“html.parser”

with open('D:/爬虫测试/data1.txt', 'r+', encoding='UTF-8') as f:
f.write(soup.text)

# 定义好相关列表准备存储相关信息
name = [] # 动漫名字
jsk = [] #集数库
bfl = [] # 播放量
scs = [] # 收藏数


# ******************************************** 动漫名字存储
for tag in soup.find_all('div', class_='info'):
# print(tag)
bf = tag.a.string
name.append(str(bf))
print(name)

# ******************************************** 动漫集数
for tag in soup.find_all('div', class_='detail'):
# print(tag)
js = tag.find('span', class_='data-box').get_text()
js = re.search(r'\d*(\.)?\d', js).group()
jsk.append(int(js))
print(jsk)
# ******************************************** 动漫播放量
for tag in soup.find_all('div', class_='detail-state'):
# print(tag)
bf = tag.find('span', class_='data-box').get_text()
# 统一单位为‘万’
if '亿' in bf:
num = float(re.search(r'\d(.\d)?', bf).group()) * 10000
# print(num)
bf = num
else:
bf = re.search(r'\d*(\.)?\d', bf).group()
bfl.append(float(bf))
print(bfl)

# ******************************************** 收藏数
for tag in soup.find_all('div', class_='detail-state'):
sc = tag.find('span', class_='data-box').next_sibling.next_sibling.get_text()
sc = re.search(r'\d*(\.)?\d', sc).group()
scs.append(float(sc))
print(scs)

# 存储至excel表格中
info = {'动漫名': name,'集数库': jsk, '播放量(万)': bfl, '收藏数(万)': scs}
dm_file = pandas.DataFrame(info)
dm_file.to_excel('Data.xlsx', sheet_name="动漫数据分析")
# 将所有列表返回
return name, jsk, bfl, scs

def view(info):
#取出列表数据
dm_name = info[0] # 番剧名
dm_episodes = info[1] # 动漫集数
dm_play = info[2] # 番剧播放量
dm_favorite = info[3] # 番剧收藏数

#使图上的数据可以显示中文
plt.rcParams['font.sans-serif'] = ['SimHei'] #运行配置参数中的字体(font)为黑体(SimHei)
plt.rcParams['axes.unicode_minus'] = False #运行配置参数总的轴(axes)正常显示正负号(minus)
# **********************************************************************播放量和收藏量数对比
# *******播放量条形图
fig, ax1 = plt.subplots()
plt.bar(dm_name, dm_play, color='cyan')
plt.title('播放量和收藏量数据分析')
plt.ylabel('播放量(万)')
ax1.tick_params(labelsize=6)
plt.xticks(rotation=90, color='green')

# *******收藏量折线图
ax2 = ax1.twinx() # 组合图必须加这个
ax2.plot(dm_favorite, color='green') # 设置线粗细,节点样式
plt.ylabel('收藏量(万)')
plt.plot(1, label='播放量', color="cyan", linewidth=5.0)
plt.plot(1, label='收藏量', color="green", linewidth=1.0, linestyle="-")
plt.legend()
plt.savefig(r'D:/爬虫测试/1.png', dpi=1000, bbox_inches='tight')

plt.show()


def main():
url = 'https://www.bilibili.com/v/popular/rank/bangumi' # 网址
html = get_html(url) # 获取返回值
# print(html)
info = save(html)
view(info)


if __name__ == '__main__':
main()

 

实验结果:

 

 

 

最后在putty上运行

putty运行过程:

1.putty登录

 

 

2.winscp登录和上传文件

 

 

 

 

3.putty下载库(调试环境)

      首先,我用的putty服务器类型属于linux,同时已经有了python3.7.2,大家可以先用python --version,测试自己的python版本,版本比较低的可以去下载

      对于我的代码中所用的库,如(re,bs4,matplotlib.pyplot,pandas等)可以用pip3 install  XXXX(这里输入你所用库的名字,例如:pip3 install Pandas)

      pip3 lists 可以检测自己当前所有的库(如下图)

 

 

下载好了库就尝试运行了,但是这里有个问题,代码中例如:‘D:/爬虫测试/Data1'等和自己电脑每个地址连接的地方,放入Winscp之后要重新在Winscp中重新新建这些文件,并更换成新的地址

 

最后进行代码得运行 python3 XXXXX.py(你所导入py文件的名字,例如我的就是 python3  pythonceshi.py)

运行结果如下:

 

 

 

   Winscp里面的新建的data1.txt 和 1.png也会和上面的运行结果一样,在此不再次作展示了,感兴趣的小伙伴们都可以拿去试试,如果哪里有不太好的地方,或者有更优化的方案,欢迎随时来找我讨论。

 

 

三、解析补充

1.库的介绍

re:正则表达式(英文名称:regular expression,regex,RE)是用来简洁表达一组字符串特征的表达式。最主要应用在字符串匹配中。

Pandas :  一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析,式分析结构化数据的工具集,是 Numpy 库的一个子库,可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。

openpyxl :是一个用于处理 xlsx 格式 Excel 表格文件的第三方 python 库,其支持 Excel 表格绝大多数基本操作。

Requests :  在 urllib 的基础上开发而来,它使用 Python 语言编写,并且采用了 Apache2 Licensed(一种开源协议)的 HTTP 库。用于网页的爬取。

BS4 :  Beautiful Soup 简称 BS4(其中 4 表示版本号)是一个 Python 第三方库,它可以从 HTML 或 XML 文档中快速地提取指定的数据。

matplotlib.pyplot : 绘制各类可视化图形的命令子库,用户可通过调用pyplot使用Matplotlib中所有可视化的类.

2.代码的使用补充

  上面的代码分享,我已做了一部分批注,在这一块在对我认为可能有问题的地方进行一些介绍和补充

1).链接本机文件地址的问题

  with open('D:/爬虫测试/data1.txt', 'r+', encoding='UTF-8') as f:

  f.write(soup.text)

 

  plt.savefig(r'D:/爬虫测试/1.png', dpi=1000, bbox_inches='tight')

 

 

上面黄色部分,是你所保存爬取内容的文件,以及后续保存表格的地方,需要找到你电脑中该文件的位置,位置不固定,写对所放地址就好。


2).函数的介绍

 

 (1)

 def get_html(url):

 获取网页,对数据是否异常进行判断,获取网页编码方式

 (2)

 def save(html):


  先解析网页内容并进行保存,之后利用正则表达式(下面黄色内容)从中选择出所需的数据,进行打印并保存到excel表格中,例如:

 (3)

 js = re.search(r'\d*(\.)?\d', js).group()

(该部分有一个问题,如何从网页那么大量的信息中筛选出自己所需的那一部分数据,我在后面会简单介绍如何看网页的源代码。)
(4)
def view(info):

列出所用信息,并制作柱状图和折线图
dm_XXXX = info[Y]  

“XXXX”为你的数据起名字,Y对应着上面第Y-1个(和数组一样,从0开始)的info,也就是save中提取出来的字符串数组。
plt.bar(dm_name, dm_play, color='cyan')
plt.bar()里面是所调用的数据(如dm_name,dm_play),以及对应的颜色(color=‘’)。
plt.title()图表名字
plt.ylabel()图表纵坐标名字
plt.xlabel()图表横坐标名字


3)网站源代码的查看



 这样一大个源代码乍一看很猛,一堆字母不懂啊,别急首先我们先可以从英文单词下手。

head : 头部(网站顶部); body:身体(内容); foot:脚。

接着我们可以光标放在我们想知道的那行代码上,这时网页会对应显示这句代码的作用范围,如下图:

 

 

这样的话我们就可以一点一点找,找到如下内容,当然到这里有人会说,选中所要查的内容,直接F12,就可以查所选内容的源代码啊。

的确如此,但是,对于这个网页可能不是很方便,首先,我们所要查的内容都有链接,本人在操作时右键经常无法选中,而是就会被误判为点击链接,跳转至视频,相对麻烦。

而且接下去,还有一个”next_sibling“代码使用的原因,需要全代码才更好理解。

 

 

见上图,我用红色找出了所需要的数据,黄色找出了他们所对应区域的标签。

全文都是用div分割成一块一块,所以我们代码中就是先从带有div标签中寻找,然后class(我理解就是标签,class后面就可以放上我们黄色标签的内容)

于是:

(=>手工箭头的意思)

class_=’info‘     =>   动漫名字

class_=’detail‘  =>   动漫更新集数

class_=’detail-state‘     =>   动漫播放量和收藏量

  问题来了,动漫集数和收藏量在一起,如果不分开就会出现这样的结果

 

  大家就会发现第三部分明显包括了第四部分,所以这时候用了next_sibling,大家可以看第二张源代码图,收藏量在播放量下面的两行之外,于是我们就放入两个next_sibling,相当于将前面的播放量跳开,数据的搜集就会直接识别并保存收藏量了,这样就达到我们想要的结果了。

   4)知识点补充

      在进行该实验过程中,查到一些资料,有的以前上课提到过,有的是我这里库的使用,在此做一个补充,可供大家回顾和进一步修改该代码

 (1)文件读写操作:

    r: 以只读方式打开文件。文件的指针将会放在文件的开头。这是**默认模式**。
    rb: 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
    r+: 打开一个文件用于读写。文件指针将会放在文件的开头。
    rb+:以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
    w: 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    wb: 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    w+: 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    wb+:以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    a: 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
    ab: 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
    a+: 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
    ab+:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

 (2)对于制作表格时的ax

   direction/tickdir : 可选{‘in’, ‘out’, ‘inout’}刻度线的方向
   size/length : float, 刻度线的长度
   width : float, 刻度线的宽度
   color : 刻度线的颜色,我一般用16进制字符串表示,eg:’#EE6363’
   labelsize : float/str, 刻度值字体大小
   labelcolor : 刻度值颜色

   plt.savefig()对图表进行保存

   plt.show()运行时运行图表,进行展示

 

 

(3)对于文件的处理

   f是flie的缩写,是对于文件的一个处理,以下还有其他使用方式的补充:

 

   file.read([size])   将文件数据作为字符串返回,可选参数size控制读取的字节数
file.readlines([size]) 返回文件中行内容的列表,size参数可选
file.write(str) 将字符串写入文件
file.writelines(strings) 将字符串序列写入文件
file.close() 关闭文件
file.closed 表示文件已经被关闭,否则为False
file.mode Access文件打开时使用的访问模式
file.encoding 文件所使用的编码
file.name 文件名
file.newlines 未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表
file.softspace 为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般程序员用不着,由程序内部使用

 

 

 

 

 

四、实验过程中遇到的问题

 

问题一:最初 X-shell 没有下载成功

问题一解决办法:询问了老师,改用putty+Winscp

 

问题二:网页源代码不会看

问题二解决办法:自己打开了网页源代码,自己一点点尝试,最后发现了规律。

 

问题三:许多代码没见过,或者有的见过也不是很会用

问题三解决办法:自己一点点上网查,把源代码中包含的那一部分不断修改参数,删掉一部分等方式,观察输出结果的变化,一点点摸索代码的作用。

 

问题四:putty上环境调试有问题,运行指令不会。

问题四解决办法:询问同学时发现自己搞错了操作系统类型,自己申请的华为云ESC弹性服务器是linux,并且自身就已经是python3了,用的是yum而不是adt-get。

 

问题五:pandas库下载有问题,一直报错

问题五解决办法:在同学的帮助和上网查询下升级了自己的pip,然后就可以了。

 

问题六:源代码时间比较早,和当前有些出入

问题六解决办法:自己一点点尝试,一点点查,根据现在的网页界面进行修改。

 

五、个人感悟

   这是python课程的最后一次实验,这个实验的完成也代表着我的python修选课之旅可能要暂告一段落,内心其实还是感慨的。作为选修的python,相比于必修C语言而言,压力比较小,个人也比较享受学习python的过程,而且课程里安排的练手小程序很有意思,python的世界非常丰富多彩。课程结束了,课堂上王老师教的知识很多,或许我没能全部学会,有不少代码依旧不太会使用,但是我对python的兴趣越来越大。课程或许结束了,但是我在python世界里的探索或许才刚刚开始。 

   在本次python之旅种,我做了小学生计算题出题系统,然后是tk库界面设计的计算器,之后又是turtle库的国旗,玫瑰花,然后第一次尝试给别人的产品做测评,不久又是进行了通过python建立起来的局域网内加密通话,虽然我自己尝试的那个远远不及真正的交流软件,最后就是本次爬虫爬取信息做数据处理和可视化处理的实验。回顾这些实验的过程,或许实验的时候又很多很多不会,查资料查半天也可能没有查明白,程序不断的报错,但是现在我觉得都很值得的,因为在这个过程中我学到了许多东西,我做到了许多我曾经认为不可能的事。

   在此谢谢王志强老师的python课堂,每一节课都很有意思,没有想象中的刻板与严肃,而是活泼又有趣,少了一般课堂的死气沉沉,多了许多同学的好奇敲码。这一段时间真的很开心,很有趣,以后虽然课程结束了,但我依旧会继续在python的世界里继续遨游,做自己喜欢的程序,享受在python世界的快乐,最起码还有一个pygame的库还没有尝试过。

 

六、相关文献参考

 

https://www.php.cn/python-tutorials-423456.html

 

append 在python中什么意思

 

https://blog.csdn.net/Fwuyi/article/details/123084642

 

plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘]

 

plt.rcParams[‘axes.unicode_minus‘] = False

 

https://blog.csdn.net/weixin_43360707/article/details/101034944

 

如何进行网页异常的判断

 

https://blog.csdn.net/Jacompol/article/details/111692298?ops_request_misc=&request_id=&biz_id=102&utm_term=python%E7%88%AC%E8%99%AB%E4%BB%A5%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-111692298.142^v11^control,157^v12^new_style&spm=1018.2226.3001.4187

源代码

 

https://www.bilibili.com/v/popular/rank/bangumi

爬取的网站

 

https://blog.csdn.net/A78562/article/details/119678326

linux环境pip更新命令

 

标签:文件,plt,name,Python,html,tag,实验报告,20214302,class
来源: https://www.cnblogs.com/cds456/p/16319329.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有