码迷,mamicode.com
首页 > 编程语言 > 详细

Python 爬取B站UP主的所有视频链接及详细信息

时间:2020-11-23 12:09:26      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:BMI   ide   clear   初始   其它   重启   死亡人数   还需要   版本   

标题:Python 爬取B站UP主的所有视频链接及详细信息

原文链接:https://blog.xieqiaokang.com/posts/36033.html
Github:https://github.com/xieqk/Bilibili_Spider_by_UserID.git
Gitee:https://gitee.com/xieqk/Bilibili_Spider_by_UserID.git

环境准备

  • selenium
  • bs4

安装

这里使用 conda 安装,也可使用 pip

conda install selenium bs4

selenium是一个操作浏览器的 Python 库,需要安装相应的浏览器驱动,如 firefox:

conda install gtk3 firefox -c conda-forge

此外还需要 geckodriver ,可前往 github 下载,并放置于 /usr/local/bin/

  • 也可以放置在自定义路径下(但须为环境变量能够找到的地方),如非管理员用户可放置于自己 home 目录下的 ~/bin 目录下,并将该路径添加进环境变量:
export PATH=~/bin${PATH:+:${PATH}}

如果需要永久将 ~/bin 路径添加进环境变量,则将上述语句添加进 ~/.bashrc 文件末尾即可(重启命令行生效,或手动输入source ~/.bashrc 在当前命令行激活)。

  • Windows 需下载对应 windows 版本并放置于环境变量能够找到的地方,或手动将 geckodriver 所在路径加入 PATH 中,并重启。

快速使用

1. 安装依赖

见上一节环境准备部分,安装对应依赖环境。

2. Clone 代码

# Github (国内访问网速不佳者可使用 Gitee)
git clone https://github.com/xieqk/Bilibili_Spider_by_UserID.git
# Gitee
git clone https://gitee.com/xieqk/Bilibili_Spider_by_UserID.git

3. 查看 B 站用户 uid

如下图所示,进入该用户主页,地址栏后面红框中的数字即为该用户的 uid

技术图片

4. 爬取用户视频数据

进入代码目录中,直接执行 main.py,传入 uid 参数即可:

python main.py --uid 362548791

爬取结果将保存于当前目录下的 json 目录,以 json 格式保存,为一个列表,内容如下:

[
    {
        "user_name": "歪西歪小哥哥",	// UP主名字
        "bv": "BV1Wa4y1e7yy",	// BV号
        "url": "https://www.bilibili.com/video/BV1Wa4y1e7yy",	// 视频链接
        "title": "【新冠肺炎:全球各国+中美各省/州】累计确诊人数 & 累计死亡人数数据可视化:俄罗斯情况不容乐观",	// 标题
        "play": "3888",		// 播放量
        "duration": 796,	// 总时长
        "pub_date": "2020-05-16",	// 发布日期
        "now": "2020-11-18 15:47:28"	// 当前日期
    },
    ...
]

5. 其它参数

  • --save_dir:保存 json 结果的目录,默认为 json
  • --save_by_page:按页保存用户视频信息,默认为 False(B站用户视频页一页一般为30个视频)。
  • --time:爬取时,浏览器获取页面的等待时间,默认为 2(秒)。网络状况不佳时等待时间过短可能会导致爬取的数据不完全。
  • --detailed:进一步爬取每一个链接的详细信息(弹幕数、是否为播放列表、发布日期及时刻、,默认为 False

当加入 --detailed 参数后每个 url 的爬取结果为:

[
    {
        "user_name": "歪西歪小哥哥",
        "bv": "BV1Wa4y1e7yy",
        "url": "https://www.bilibili.com/video/BV1Wa4y1e7yy",
        "title": "【新冠肺炎:全球各国+中美各省/州】累计确诊人数 & 累计死亡人数数据可视化:俄罗斯情况不容乐观",
        "play": "3888",
        "duration": 796,
        "pub_date": "2020-05-16 02:17:16",	// 发布日期精确到时分秒
        "now": "2020-11-18 15:47:28",
        "danmu": "85",
        "type": "playlist",		// 链接类型:‘video‘代表单个视频,‘playlist‘代表播放列表
        "num": 4	// 分P数,如果为‘video‘则为1,‘playlist‘则为播放列表的视频集数
    },
    ...
]

详细说明

详见 utils/bilibili_spider.pyBilibili_Spider()

1. 初始化

options = webdriver.FirefoxOptions()
options.add_argument(‘--headless‘)
self.browser = webdriver.Firefox(options=options)

2. 获取用户视频页数及用户名

  • 获取用户主页下视频页的第一页:
self.user_url = ‘https://space.bilibili.com/{}‘.format(uid)
page_url = self.user_url + ‘/video?tid=0&page={}&keyword=&order=pubdate‘.format(1)
self.browser.get(page_url)
time.sleep(self.t+2*random.random())
html = BeautifulSoup(self.browser.page_source, features="html.parser")
  • 获取视频页数:找到页数所在位置,浏览器打开页面后在对应位置检查即可。

技术图片

page_number = html.find(‘span‘, attrs={‘class‘:‘be-pager-total‘}).text
page_number = int(page_number.split(‘ ‘)[1])
  • 获取用户名

技术图片

user_name = html.find(‘span‘, id = ‘h-name‘).text

3. 获取每一页的视频信息

获取该页视频列表,并遍历

技术图片

page_url = self.user_url + ‘/video?tid=0&page={}&keyword=&order=pubdate‘.format(idx+1)	# idx 为视频第几页
self.browser.get(page_url)
time.sleep(self.t+2*random.random())
html = BeautifulSoup(self.browser.page_source, features="html.parser")

ul_data = html.find(‘div‘, id = ‘submit-video-list‘).find(‘ul‘, attrs= {‘class‘: ‘clearfix cube-list‘})

for li in ul_data.find_all(‘li‘):
    # 获取每个视频的信息:url、标题、日期等

4. 获取每个视频信息

技术图片

for li in ul_data.find_all(‘li‘):
    # 链接和标题
    a = li.find(‘a‘, attrs = {‘target‘:‘_blank‘, ‘class‘:‘title‘})
    a_url = ‘https:{}‘.format(a[‘href‘])
    a_title = a.text
    # 发布日期及播放数
    date_str = li.find(‘span‘, attrs = {‘class‘:‘time‘}).text.strip()
    pub_date = self.date_convert(date_str)
    now = datetime.datetime.now().strftime(‘%Y-%m-%d %H:%M:%S‘)
    play = int(li.find(‘span‘, attrs = {‘class‘:‘play‘}).text.strip())
    # 总时长
    time_str = li.find(‘span‘, attrs = {‘class‘:‘length‘}).text
    duration = self.time_convert(time_str)

5. 进入视频页获取信息

  • 获取视频详细数据

技术图片

# e.g. url = ‘https://www.bilibili.com/video/BV1Wa4y1e7yy‘
self.browser.get(url)
time.sleep(self.t+2*random.random())
html = BeautifulSoup(self.browser.page_source, features="html.parser")

video_data = html.find(‘div‘, id = ‘viewbox_report‘).find_all(‘span‘)
play = int(video_data[1][‘title‘][4:])
danmu = int(video_data[2][‘title‘][7:])
date = video_data[3].text
  • 判断是否为播放列表

检查是否有 multi_page 字段即可判断是否为播放列表。

技术图片

# 接上一段代码:“进入视频页获取视频的详细信息”
multi_page = html.find(‘div‘, id = ‘multi_page‘)
if multi_page is not None:
    url_type = ‘playlist‘
    pages = multi_page.find(‘span‘, attrs= {‘class‘: ‘cur-page‘}).text
    page_total = int(pages.split(‘/‘)[-1])
else:
    url_type = ‘video‘
    page_total = 1
# 也可继续获取播放列表其它信息,如分P的标题,但如果爬取时sleep时间过短可能导致爬取失败。

Python 爬取B站UP主的所有视频链接及详细信息

标签:BMI   ide   clear   初始   其它   重启   死亡人数   还需要   版本   

原文地址:https://www.cnblogs.com/xieqk/p/bilibili-spider-user-uid-video.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!