魔道书生 发表于 2020-6-29 09:46

求助抓B站视频接口

本帖最后由 魔道书生 于 2020-6-29 09:50 编辑

最近论坛好多大佬都在发B站视频下载
自己心里也痒痒
参考了@xccxvb 的帖子https://www.52pojie.cn/thread-1203086-1-1.html
看了他的源码

api_url = 'https://api.bilibili.com/x/player/playurl?cid={}&avid={}&qn={}&otype=json&requestFrom=bilibili-helper'api_url = 'https://api.bilibili.com/x/player/playurl?cid={}&avid={}&qn={}&otype=json&requestFrom=bilibili-helper'

想知道这个api是怎么抓到的
我抓了N遍也没找到???

我看直链就是类似
http://cn-jstz-dx-v-01.bilivideo.com/upgcxcode/84/90/206729084/206729084-1-16.mp4?expires=1593402542&platform=pc&ssig=tBBeKFj80KZeeCWi5tnmZA&oi=1779007583&trid=13176c3336bf47b5ab22d89eb2daa3aeu&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&cdnid=4965&mid=0&orderid=0,3&logo=80000000
这样的 直接打开返回453 但是却能下载????????

并没有看到有关视频url的接口
每个XHR我都看了 看不到返回视频URL的
求大佬指点

井右寺 发表于 2020-6-29 10:31

我这里有一份之前帮同事做的下载工具,不过不是通过包抓取的,直接是页面分析(BTW,其实我自己懒得去看,直接在网上找的别人的,感谢已经被我忘记的大佬)
代码如下(ffmpeg这个工具网上下载就好)
import requests, threading
import json, os, time, random
from lxml import etree
import subprocess

def readList():
        res = []
        try:
                with open("videos.txt", 'r') as f:
                        line = f.readline().strip()
                        while line:
                                if not line in res:
                                        res.append(line)

                                line = f.readline().strip()

        except:
                pass

        return res

# 防止因https证书问题报错
requests.packages.urllib3.disable_warnings()

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3970.5 Safari/537.36',
        'Referer': 'https://www.bilibili.com/'
}


def GetBiliVideo(homeurl,session=requests.session()):
        res = session.get(url=homeurl, headers=headers, verify=False)
        html = etree.HTML(res.content)
        videoinforms = str(html.xpath('//head/script/text()'))
        videojson = json.loads(videoinforms)
        # 获取视频链接和音频链接
        VideoURL = videojson['data']['dash']['video']['baseUrl']
        AudioURl = videojson['data']['dash']['audio']['baseUrl']
        #print(videojson)
        #获取视频资源的名称
        name = str(html.xpath("//h1/@title")).strip().replace(" ", "")

        # 下载视频和音频
        dv = threading.Thread(target=BiliBiliDownload, kwargs={"homeurl": homeurl, "url": VideoURL, "Video": True, "session": session, "name": name})
        av = threading.Thread(target=BiliBiliDownload, kwargs={"homeurl": homeurl, "url": AudioURl, "Video": False, "session": session, "name": name})
        dv.start()
        av.start()
        dv.join()
        av.join()

        print("开始合并%s音视频" %name)

        avpath = "./%s/%s_audio.mp4" %(name, name)
        dvpath = "./%s/%s_video.mp4" %(name, name)
        outpath = "./%s/%s.mp4" %(name, name)
       
        CombineVideoAudio(avpath, dvpath, outpath)

        # 开始合并音视频



def BiliBiliDownload(homeurl, url, name,Video=True,session=requests.session()):
        headers.update({'Referer': homeurl})
        session.options(url=url, headers=headers,verify=False)

        path = "./%s" %name
        loop =True
        while loop:
                try:
                        if not os.path.exists(path):
                                os.mkdir(path)

                        loop = False
                except Exception as e:
                        print(e)
                        time.sleep(random.randint(1, 100))


        _type = "音频"

        filetype="audio"
        if Video:
                _type = "视频"
                filetype="video"

        file = "%s/%s_%s.mp4" %(path, name, filetype)

        print("开始下载 %s%s 文件" %(name, _type))
        # 每次下载1M的数据
        begin = 0
        end = 1024*512-1
        flag=0
        while True:
                headers.update({'Range': 'bytes='+str(begin) + '-' + str(end)})
                res = session.get(url=url, headers=headers,verify=False)
                if res.status_code != 416:
                        begin = end + 1
                        end = end + 1024*512
                else:
                        headers.update({'Range': str(end + 1) + '-'})
                        res = session.get(url=url, headers=headers,verify=False)
                        flag=1
                with open(file, 'ab') as fp:
                        fp.write(res.content)
                        fp.flush()

                # data=data+res.content
                if flag==1:
                        fp.close()
                        break
        print("文件 %s%s 下载完成" %(name, _type))


def CombineVideoAudio(videopath, audiopath, outpath):
        try:
                subprocess.call("ffmpeg.exe -i %s -i %s -vcodec copy -acodec copy %s" %(videopath, audiopath, outpath))
                os.remove(videopath)
                os.remove(audiopath)
                print("%s 音视频合并完成" %outpath)
        except:
                print("%s 音视频合成失败" %outpath)

if __name__ == '__main__':
        start = time.time()
        print("%s欢迎使用bilibili视频下载器%s" %('='*10, '='*10))
        print("%s仅供学习交流使用,请勿用作它途%s" %('='*10, '='*10))
        print()
       
        urls = readList()

        print("共有 %s 个视频待下载" %len(urls))

        threads = []

        for url in urls:
                threads.append(threading.Thread(target=GetBiliVideo, args=(url,)))

        for t in threads:
                t.start()

        for t in threads:
                t.join()

        cost = time.time() - start
        if cost/1000 > 3:
                cost = "%s s" %int(cost/1000)
        else:
                cost = "%s ms" %int(cost)

        print()
        print('='*350)
        print("所有视频下载完成,用时 %s" %cost)
       
        input("输入任意键以退出程序")
       

日后提拔 发表于 2020-6-29 10:45

向大佬学习

黑龍 发表于 2020-6-29 10:47

有可能是app接口   b站很多接口都是passport开头的二级域名

魔道书生 发表于 2020-6-29 10:58

黑龍 发表于 2020-6-29 10:47
有可能是app接口   b站很多接口都是passport开头的二级域名

那就不知道了啊   等大佬吧{:1_937:}

eWVhaA 发表于 2020-6-29 11:40

https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/PlayerAPI.kt
这是app逆向出来的接口吧。。

zdnyp 发表于 2020-6-29 11:51

eWVhaA 发表于 2020-6-29 11:40
https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/Pl ...

也是抓到m4s合并的

魔道书生 发表于 2020-6-29 12:19

eWVhaA 发表于 2020-6-29 11:40
https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/Pl ...

好像不是把大佬上面那个接口直接就是flv不用合并

hostwj 发表于 2020-6-29 15:29

记一次查找bilibili视频API的经历

在视频放完之后可以看到刷出来的新视频时直接调用API接口的
https://attach.52pojie.cn/forum/202006/29/151332j9p0a7kq8ujzqa9r.png
页: [1]
查看完整版本: 求助抓B站视频接口