头图

Python系列爬虫之B站Top100小视频下载

Cooci

前言

今天给大家介绍下载B站top100小视频,让我们愉快地开始吧~

开发工具

Python版本:3.6.4
相关模块:

requests模块;

click模块;

以及一些python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理简介

首先,当然是打开B站小视频所在的网址:

http://vc.bilibili.com/p/eden/rank#/?tab=%E5%85%A8%E9%83%A8

然后打开开发者模式,简单抓包可以发现请求以下这个链接就可以返回视频的真实地址:

请求该链接需要携带的参数包括:

page_size: 10    # 显然,参数含义是每页返回几个视频呗
next_offset:     # 往下翻页可以发现第二页的值为11, 第三页为21,所以应该是当前偏移量
tag: 今日热门    # 标签,值固定
platform: pc     # 声明平台,值固定

根据上面的分析结果,定义个函数来自动获取B站前100个小视频的链接吧:

'''获取B站前top_n个小视频的链接'''
def getVideoTopNLinks(top_n):
  assert top_n > 0, '<top_n> in function getVideoTopNLinks must be larger than zero.'
  print('[INFO]: Start to get video topn links...')
  info_url = 'http://api.vc.bilibili.com/board/v1/ranking/top?'
  headers = {
        'Referer': 'http://vc.bilibili.com/p/eden/rank',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
      }
  params_base = {
          'page_size': 10,
          'next_offset': -10,
          'tag': '今日热门',
          'platform': 'pc'
          }
  video_infos = []
  while True:
    params_base['next_offset'] += params_base['page_size']
    if top_n <= 10:
      params_base['page_size'] = top_n
      top_n = 0
    else:
      top_n = top_n - 10
    try:
      res = requests.get(info_url, params=params_base, headers=headers)
      items = res.json()['data']['items']
      for item in items:
        title = item['item']['description']
        for char in '/::*??"<>|':
          title = title.replace(char, '')
        link = item['item']['video_playurl']
        video_infos.append([title, link])
        print('[INFO]: Got %s...' % title)
    except:
      print('[Warnning]: Something error when getting video links...')
    if top_n <= 0:
      break
    time.sleep(random.random() * 2)
  print('[INFO]: Finish, get %d links in total...' % (len(video_infos)))
  return video_infos

然后写个下载视频的函数:

'''下载单个视频'''
def downloadVideo(video_info, savepath):
  checkDir(savepath)
  savename, video_link = '%s.mp4' % video_info[0], video_info[1]
  headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
      }
  with closing(requests.get(video_link, headers=headers, stream=True, verify=False)) as res:
    total_size = int(res.headers['content-length'])
    if res.status_code == 200:
      label = '[%s, FileSize]:%0.2f MB' % (savename, total_size/(1024*1024))
      with click.progressbar(length=total_size, label=label) as progressbar:
        with open(os.path.join(savepath, savename), "wb") as f:
          for chunk in res.iter_content(chunk_size=1024):
            if chunk:
              f.write(chunk)
              progressbar.update(1024)

最后遍历得到的视频链接列表下载这些视频就大功告成啦:

for video_info in video_infos:
    try:
      downloadVideo(video_info, savepath)
    except:
      print('[Warnning]: Fail to download %s...' % video_info[1])

为了帮助提升正在学习Python编程的伙伴们,在这里为大家准备了丰富的学习大礼包

image

All done~ 完整源代码详见个人简介获取相关文件~

阅读 183
239 声望
20 粉丝
0 条评论
你知道吗?

239 声望
20 粉丝
宣传栏