一、需求和规格说明
问题描述:
获取每日推荐榜单的视频链接,以及视频播放量、点赞、投币等基本信息,并储存在表格文件中
二、设计
2.1 设计思想
整体框架为爬虫,首先查看网页源码,找出数据存在部分的关键字,为了减少对网页代码解析的工作量,利用BeautifulSoup模块帮助解析html网页,获取title标签,作为接下来爬取的目标,接下来用request,get方法获取网页text类型的信息,依次获取name以及播放量,点赞量,投币数量,视频链接地址等信息,最后按视频类别爬取,对应好链接地址以及之前获得的各种视频信息,然后依次写入到bili.xlsx文件。
2.2 设计表示
类别 | 名称 | 描述 |
函数 | bs_parse_video() | 解析网页 |
函数 | get_video() | 获取视频类别 |
函数 | bs_parse_data() | 获取视频信息 |
函数 | get_data() | 获取视频链接 |
函数 | delete_word() | 删除结点 |
函数 | soup.find_all() | 查找全部标签 |
函数 | requests.get() | 发送请求获取链接 |
函数 | output.write() | 写出文件 |
数据 | Fenqu[] | 分区列表 |
数据 | name | 视频类名 |
数据 | link | 视频链接 |
数据 | data_list[] | 存储视频信息 |
数据 | coin | 硬币数 |
数据 | Like | 点赞数 |
2.3 核心算法
利用BeautifulSoup可以简化网页解析步骤,方便的获取网页基础信息。
soup=BeautifulSoup(html,‘html.parser’)指定一种方法解析,
soup.find_all可以获取所有符合条件的标签,
requests.get发送请求获取信息,r.text 返回网页unicode 型的数据;
get_text()获得标签对象的文本数据部分,返回字符串;
将获取的信息按照视频title分类别存放,当网页获得的视频类别与设定好的类别相同时,开始检索该视频下的文本内容,获取视频播放量点赞等信息,存储在list中,利用output.open方法打开文件,并用write方法按照格式写数据到文件。
三、用户手册
创建bili.xlsx文件作为存储数据的文件,运行程序代码,等待爬取信息。
四、调试及测试
4.1 待爬取网页部分信息
4.2 爬取结果
附录
import requests
from bs4 import BeautifulSoup
def bs_parse_video(html, video_list=None) -> object:
video_list = []
soup = BeautifulSoup(html, "html.parser")
# 查找所有class属性为title的标签
div_list = soup.find_all('a', class_="title")
# 获取每个链接
for each in div_list:
video = each.get('href')
video_list.append(video)
return video_list
def get_video(name):
#网页视频分区组成
link = 'https://www.bilibili.com/v/popular/rank/' + name
r = requests.get(link)
if 200 != r.status_code:
return None
#返回文本信息
return bs_parse_video(r.text)
def bs_parse_data(html, video_list=None) -> object:
soup = BeautifulSoup(html, "html.parser")
# 查找所有class属性为ops的div标签
div = soup.find_all('div', class_="ops")
div2 = soup.find_all('div', class_="video-data")
# 判断视频是否已失效
div_error = soup.find_all('div', class_="error-body")
if div_error:
return []
#ops中的信息
if div:
# 获取点赞,投币,收藏与分享数
like = div[0].find('span', class_="like").get_text()
like = like[:-5] # 去除无效字符
coin = div[0].find('span', class_="coin").get_text()
coin = coin[7:-5]
collect = div[0].find('span', class_="collect").get_text()
collect = collect[:-5]
share = div[0].find('span', class_="share").get_text()
share = share[:-7]
a = [like, coin, collect, share]
else:
a = []
#videodata中的信息
if div2:
# 获取播放量与弹幕数
view = div2[0].find('span', class_="view").get_text()
view = view[:-5]
dm = div2[0].find('span', class_="dm").get_text()
dm = dm[:-2]
b = [view, dm]
else:
b = []
return [a, b]
#链接地址
def get_data(link):
links = 'https:' + link
r = requests.get(links)
if 200 != r.status_code:
return None
return bs_parse_data(r.text)
fenqu = ["all", "guochuang", "music", "douga", "dance", "game", "technology", "digital", "life", "food", "kichiku",
"fashion", "ent","cinephile", "origin", "rookie"]
data_list = [] # 储存已得到的数据
output = open('bili1.xlsx', 'w')
output.write('分区\t链接\t点赞\t硬币\t收藏\t分享\t播放量\t弹幕数量\n')
for name in fenqu:
movies = get_video(name)
for link in movies:
data = get_data(link)
link = link[2:]
data_list.append([name, link, data])
print([name, link, data])
if data:
if (data[0] != []) & (data[1] != []):
# 按格式读出到excel文件
output.write(str(name))
output.write('\t')
output.write(str(link))
output.write('\t')
output.write(str(data[0][0]))
output.write('\t')
output.write(str(data[0][1]))
output.write('\t')
output.write(str(data[0][2]))
output.write('\t')
output.write(str(data[0][3]))
output.write('\t')
output.write(str(data[1][0]))
output.write('\t')
output.write(str(data[1][1]))
output.write('\n')
output.flush()
output.close()