• 爬虫项目实战——爬取B站视频


    目标:对B站视频详情页url进行视频的爬取。
    注:由于B站的音频和视频的链接是分开的,所以在提取是需要分别提取,然后进行合成。
    这里只管提取,合成的工作以后再说。

    具体步骤

    1. 发送请求 对于视频详情页url地址发送请求 https://www.bilibili.com/video/BV11b4y1S7Jg
    2. 获取数据 获取响应体的文本数据 response.text 网页源代码
    3. 解析数据 提取我们想要的 视频标题/音频url/视频画面url,
    4. 保存数据, 对于音频url 视频url发送请求 获取响应体二进制数据 response.content
    5. 合成数据,把音频内容以及视频画面内容合成为一个完整的mp4文件

    1. 发送请求

    说明:
    Referer:是防盗链。表示当前这个链接,我是从哪个链接跳转过来的。
    Cookie:由于B站不登陆只能下载

    url = 'https://www.bilibili.com/video/BV1Bo4y1v7Yq/'
    response = requests.get(url)
    cookie = "buvid3=5C5D0069-031F-2213-8E11-3B17C971719F69389infoc; b_nut=1688698369; _uuid=7F76CBFD-ADE2-44103-424C-D73D5E9ACC2869255infoc; header_theme_version=CLOSE; CURRENT_FNVAL=4048; buvid4=780B8373-C6A6-6800-F372-7CF18F799AE570981-023070710-7YWVed7pFp%2FuoShCfdfYnQ%3D%3D; DedeUserID=175444232; DedeUserID__ckMd5=b4a676bf5d8afe1c; rpdid=|(k|)mum~~uJ0J'uY))~|uklm; LIVE_BUVID=AUTO5916888971292528; SESSDATA=6b25c9b2%2C1705192174%2Cba23f%2A71bQR5hFBMOt8AXYHjziKE4HOwWw6Ei8wrCIByshPnLAkTd2jwLJy4WYgVkViOyIUPNssSUQAAIAA; bili_jct=e29211bb7e88730fc2bc6691218d247e; sid=858nix09; FEED_LIVE_VERSION=V8; buvid_fp_plain=undefined; hit-new-style-dyn=1; hit-dyn-v2=1; i-wanna-go-back=-1; b_ut=5; fingerprint=b2371c9349b15d5ad60e75cd01f7dc55; buvid_fp=5b9a1047d9ef9ba48290adcd4ba39e58; share_source_origin=copy_web; bsource=share_source_copylink_web; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTY0NzMzNjcsImlhdCI6MTY5NjIxNDEwNywicGx0IjotMX0.D2ixQib5vaXOyxTBLWhIR8KzpbGQloGjxzXDgnOum3E; bili_ticket_expires=1696473307; CURRENT_QUALITY=80; b_lsid=4F245FCD_18AFACA514A; home_feed_column=5; browser_resolution=1552-827; bp_video_offset_175444232=848638555060174904; PVID=1"
    
    head = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    
        # Referer: 防盗链。用于告诉服务器我是从哪个链接跳转来的。
        'Referer': 'https://www.bilibili.com/',
        'Cookie': cookie
    }
    sleep(2)
    page_text = response.text
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2. 获取数据

    # 获取标题和播放信息
    tree = etree.HTML(page_text)
    title = tree.xpath('//*[@id="viewbox_report"]/h1/text()')[0]
    play_info = tree.xpath('/html/head/script[4]')[0].text      # 通过tree.xpath得到script对象,然后通过text属性得到其内容
    play_info = play_info[20:]      # 去掉前面的window.__playinfo__=这几个字符
    print(play_info)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 解析数据

    # 将数据转为json格式,方便获取其中的部分数据
    play_info_json = json.loads(play_info)
    # print(play_info_json)
    pprint.pprint(play_info_json)   # 格式化输出
    
    # 获取音频、视频url
    # B站的音频和视频链接是分开的,所以要分别获取,然后通过一定的方法进行合并。
    video_url = play_info_json['data']['dash']['video'][0]['baseUrl']   # 得到视频链接
    audio_url = play_info_json['data']['dash']['audio'][0]['baseUrl']   # 得到音频链接
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4. 保存数据

    video_content = requests.get(url=video_url, headers=head).content   # content表示二进制数据
    audio_content = requests.get(url=audio_url, headers=head).content		#  # content表示二进制数据
    
    if not os.path.exists('./B站视频'):
        os.mkdir('./B站视频')
    
    with open('./B站视频/'+title+'.mp4', 'wb') as fp:
        fp.write(video_content)
    
    with open('./B站视频/'+title+'.mp3', 'wb') as fp:
        fp.write(audio_content)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    完整代码

    import json
    import os.path
    
    import requests
    from time import sleep
    from lxml import etree
    import pprint
    
    # 已成功
    
    """
    1.发送请求 对于视频详情页url地址发送请求 https://www.bilibili.com/video/BV11b4y1S7Jg
    2.获取数据 获取响应体的文本数据 response.text 网页源代码
    3.解析数据 提取我们想要的 视频标题/音频url/视频画面url,
    4保存数据, 对于音频url 视频url发送请求 获取响应体二进制数据 response.content
    5.合成数据,把音频内容以及视频画面内容合成为一个完整的mp4文件
    """
    url = 'https://www.bilibili.com/video/BV1Bo4y1v7Yq/'
    response = requests.get(url)
    cookie = "buvid3=5C5D0069-031F-2213-8E11-3B17C971719F69389infoc; b_nut=1688698369; _uuid=7F76CBFD-ADE2-44103-424C-D73D5E9ACC2869255infoc; header_theme_version=CLOSE; CURRENT_FNVAL=4048; buvid4=780B8373-C6A6-6800-F372-7CF18F799AE570981-023070710-7YWVed7pFp%2FuoShCfdfYnQ%3D%3D; DedeUserID=175444232; DedeUserID__ckMd5=b4a676bf5d8afe1c; rpdid=|(k|)mum~~uJ0J'uY))~|uklm; LIVE_BUVID=AUTO5916888971292528; SESSDATA=6b25c9b2%2C1705192174%2Cba23f%2A71bQR5hFBMOt8AXYHjziKE4HOwWw6Ei8wrCIByshPnLAkTd2jwLJy4WYgVkViOyIUPNssSUQAAIAA; bili_jct=e29211bb7e88730fc2bc6691218d247e; sid=858nix09; FEED_LIVE_VERSION=V8; buvid_fp_plain=undefined; hit-new-style-dyn=1; hit-dyn-v2=1; i-wanna-go-back=-1; b_ut=5; fingerprint=b2371c9349b15d5ad60e75cd01f7dc55; buvid_fp=5b9a1047d9ef9ba48290adcd4ba39e58; share_source_origin=copy_web; bsource=share_source_copylink_web; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTY0NzMzNjcsImlhdCI6MTY5NjIxNDEwNywicGx0IjotMX0.D2ixQib5vaXOyxTBLWhIR8KzpbGQloGjxzXDgnOum3E; bili_ticket_expires=1696473307; CURRENT_QUALITY=80; b_lsid=4F245FCD_18AFACA514A; home_feed_column=5; browser_resolution=1552-827; bp_video_offset_175444232=848638555060174904; PVID=1"
    
    head = {
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    
        # Referer: 防盗链。用于告诉服务器我是从哪个链接跳转来的。
        'Referer': 'https://www.bilibili.com/',
        'Cookie': cookie
    }
    sleep(2)
    page_text = response.text
    
    with open('./bilibili.html', 'w', encoding='utf-8') as fp:
        fp.write(page_text)
    
    # print(page_text)
    # 获取标题和播放信息
    tree = etree.HTML(page_text)
    title = tree.xpath('//*[@id="viewbox_report"]/h1/text()')[0]
    play_info = tree.xpath('/html/head/script[4]')[0].text      # 通过tree.xpath得到script对象,然后通过text属性得到其内容
    play_info = play_info[20:]      # 去掉前面的window.__playinfo__=这几个字符
    print(play_info)
    
    # 将数据转为json格式,方便获取其中的部分数据
    play_info_json = json.loads(play_info)
    # print(play_info_json)
    pprint.pprint(play_info_json)   # 格式化输出
    
    # 获取音频、视频url
    # B站的音频和视频链接是分开的,所以要分别获取,然后通过一定的方法进行合并。
    video_url = play_info_json['data']['dash']['video'][0]['baseUrl']   # 得到视频链接
    audio_url = play_info_json['data']['dash']['audio'][0]['baseUrl']   # 得到音频链接
    
    # 获取音频、视频数据
    video_content = requests.get(url=video_url, headers=head).content   # content表示二进制数据
    audio_content = requests.get(url=audio_url, headers=head).content
    
    if not os.path.exists('./B站视频'):
        os.mkdir('./B站视频')
    
    with open('./B站视频/'+title+'.mp4', 'wb') as fp:
        fp.write(video_content)
    
    with open('./B站视频/'+title+'.mp3', 'wb') as fp:
        fp.write(audio_content)
    
    print("提取到的title", title)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
  • 相关阅读:
    手撕Vuex-模块化共享数据下
    数据指标是什么?简单聊聊企业的数据指标体系
    「PHP系列」数组详解
    ElasticSearch7.3学习(十九)---- deep paging
    彻底删除Ubuntu双系统(联想小新2022)
    算法设计与分析 SCAU11090 最大m段乘积和最小m段和(优先做)
    学习学习之五星笔记法
    单体分层应用架构剖析
    matlab绘图代码(将几个数据绘制到一个figure中)
    ElasticSearch - DSL查询文档语法,以及深度分页问题、解决方案
  • 原文地址:https://blog.csdn.net/qq_45895217/article/details/133578092