《python爬虫练习》之根据BV号下载b站视频(单个)

上一篇文章简简单单的爬取了某个B站视频,这次在上一次的基础上,增加了爬取输入的BV号对应的视频。

 

上一篇里我们对网站进行分析,发现视频链接基本都存储在window.__playinfo__中,所以我们的目标也很明确。

 

 我们需要等号后面的数据,而这个window参数又在script标签中,所以我们可以很轻而易举的写出正则表达式

\<script\>window\.__playinfo__=(.*?)\</script\> 	# 需要注意的是有些字符要加’\‘进行反转义

同理,我们视频的标题也可以通过分析推敲出来

\<script\>window\.__INITIAL_STATE__=(.*?);\(function\(\)	# 因为在\</script\> 前还多了一个function方法,所以到function即可结束匹配

 正则表达式推敲出来之后,后面的工作无非就是取爬取到的视频地址数据套进下载方法罢了,所以直接上代码

import requests
import re
import json
#移除SSL认证
requests.packages.urllib3.disable_warnings()
# 请求头,伪装成浏览器访问
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
    'Accept': '*/*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br',
    'Connection': 'keep-alive'
}

# 爬取页面数据
def httpSpider(BV_mark):
    # 直接爬取HTML文件,再分析提取视频链接
    url = f"https://www.bilibili.com/video/{BV_mark}"
    try:
        response = requests.get(url, headers=headers)
        # 服务器状态码的值为200,则表示服务器接受访问请求,此时会返回页面文本文件
        if response.status_code == 200:
            return response.content.decode('utf8')
    except:
        print("请求失败")
    
    
# 获取视频标题
def rtTille(context):
    titlePattern = r'\<script\>window\.__INITIAL_STATE__=(.*?);\(function\(\)'
    title = re.findall(titlePattern, context)[0]
    titleData = json.loads(title)
    return titleData['videoData']['title']


# 获取视频链接,date['data']['dash']['video'][3]['baseUrl']存放的是720p的视频链接地址,你也可以选择其他备用地址
def filterDate(context,title):
    # .*表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
    urlPattern = r'\<script\>window\.__playinfo__=(.*?)\</script\>'
    urllist = re.findall(urlPattern, context)[0]
    date = json.loads(urllist)
    # 前两条数据(也就是存放有“id”:“80”的对应列表)里的视频链接貌似用不了,所以直接取第三条数据
    videoUrl = date['data']['dash']['video'][3]['baseUrl']
    audioUrl = date['data']['dash']['audio'][0]['baseUrl']
    print(f'正在下载 "{title}" ......')
    downView(videoUrl,f"{title}.mp4")
    downView(audioUrl,f"{title}.mp3")
    print(f'"{title}" 已下载完成.')

# 读写文件
def downView(url,title):
    res = requests.get(url, headers=headers, verify=False)
    with open(title,"wb")as f:
        f.write(res.content)
        f.close()

if __name__=="__main__":
    BV_mark = input("请输入你要下载的视频(单个)的BV号:")
    context = httpSpider(BV_mark)
    title = rtTille(context)
    filterDate(context, title)

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值