一、需求和规格说明

问题描述:

获取每日推荐榜单的视频链接,以及视频播放量、点赞、投币等基本信息,并储存在表格文件中

二、设计

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 待爬取网页部分信息

python gradio video 获取视频路径 python获取视频信息_爬虫

4.2 爬取结果

python gradio video 获取视频路径 python获取视频信息_python_02


python gradio video 获取视频路径 python获取视频信息_音视频_03


python gradio video 获取视频路径 python获取视频信息_爬虫_04

附录

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()