求助抓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的
求大佬指点
我这里有一份之前帮同事做的下载工具,不过不是通过包抓取的,直接是页面分析(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("输入任意键以退出程序")
向大佬学习 有可能是app接口 b站很多接口都是passport开头的二级域名 黑龍 发表于 2020-6-29 10:47
有可能是app接口 b站很多接口都是passport开头的二级域名
那就不知道了啊 等大佬吧{:1_937:} https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/PlayerAPI.kt
这是app逆向出来的接口吧。。 eWVhaA 发表于 2020-6-29 11:40
https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/Pl ...
也是抓到m4s合并的 eWVhaA 发表于 2020-6-29 11:40
https://github.com/czp3009/bilibili-api/blob/kotlin/src/main/kotlin/com/hiczp/bilibili/api/player/Pl ...
好像不是把大佬上面那个接口直接就是flv不用合并 记一次查找bilibili视频API的经历
在视频放完之后可以看到刷出来的新视频时直接调用API接口的
https://attach.52pojie.cn/forum/202006/29/151332j9p0a7kq8ujzqa9r.png
页:
[1]