一个获取B站视频封面的小工具
本帖最后由 Traitor 于 2022-3-28 14:04 编辑刚入门Python的小菜鸡,用的是面向过程写的,代码有点乱,有什么问题还望指出,代码有点长。
最下面有开源地址和附件
说明:
1.如果视频的分p则直接输出每个视频的封面信息,不是则输出一个视频的封面信息。
2.每集番剧封面也就是带有ep号的表示某一集,电影封面也是带ep号。
3.md链接则是直接获取该番剧的全部封面,一般点击b站番剧下面的番剧标题,就可以进入到该番剧的md链接下了。
链接样式:
https://www.bilibili.com/video/BV1wu411B7rA?spm_id_from=333.851.b_7265636f6d6d656e64.1
【warframe 新披饰 哪吒同款战损版 这次就原谅你了 奸商导购-哔哩哔哩】
https://b23.tv/pkXCmvnhttps://www.bilibili.com/bangumi/play/ep426702from_spmid=666.25.titbit.0
【《Re:从零开始的异世界生活 第二季 后半》 NCOP-哔哩哔哩番剧】
https://b23.tv/ep400067https://www.bilibili.com/bangumi/play/ss40260from_spmid=666.4.0.0
https://www.bilibili.com/video/av679711482
注意:
1.还有一种视频是分p但是不能获取全部分p的封面,也算是一个小bug吧
2.如果该番剧是即将上线的情况下,md号只能获取到该番剧的海报图和相关信息,同样ss号不能获取到内容
3.如果输入了错误的信息则返回空
支持: bv号、av号、ep号、ss号、md号、带有bv号链接、av号链接、ep链接、ss号链接、md号链接、手机端分享链接直接粘贴即可
更新:2022年3月28日14:02 修改了输出内容的逻辑让代码看起来不是那么复杂
#!/usr/bin/python
# -- coding: utf-8 --
# @Author : Small_tred
# @Time : 2022/3/28 13:11
# !/usr/bin/python
# -- coding: utf-8 --
# @Author : Small_tred
# @Time : 2022/3/25 13:54
import requests
import re
import biliBV
def handleUrl(in_url):
"""判断链接是否为跳转 获取真实链接"""
b_url = re.search(r"+://[^\s]*", in_url)
if b_url is not None:
response = requests.get(b_url.group(0), allow_redirects=False)
if response.status_code == 302:
t_url = requests.get(b_url.group(0)).url
return t_url
elif response.status_code == 301:
t_url = requests.get(b_url.group(0)).url
return t_url
else:
return b_url.group(0)
def regexBv(true_url):
"""匹配BV号"""
bv_id = re.search(r'(BV.*?).{10}', true_url)
if bv_id is not None:
return bv_id.group(0)
def regexAv(true_url):
"""匹配av号"""
av_id = re.search(r"(av.*?)\d+", true_url)
if av_id is not None:
bv_id = biliBV.encode(av_id.group(0))
return bv_id
def regexEp(true_url):
"""匹配ep号"""
ep_id = re.search(r"(ep.*?)\d+", true_url)
if ep_id is not None:
return ep_id.group(0)
def regexSs(true_url):
"""匹配SS号"""
ss_id = re.search(r"(ss.*?)\d+", true_url)
if ss_id is not None:
return ss_id.group(0)
else:
return None
def regexMd(true_url):
"""匹配Med号"""
med_id = re.search(r"(md.*?)\d+", true_url)
if med_id is not None:
return med_id.group(0)
else:
return None
# 请求API
def requestsBvVideoApi(bvid):
api = "https://api.bilibili.com/x/web-interface/view?bvid="
response = requests.get(api + bvid).json()
if response["code"] == 0:
return response
def requestsEpVideoApi(epid):
api = "https://api.bilibili.com/pgc/view/web/season?ep_id="
response = requests.get(api + epid).json()
if response["code"] == 0:
return response
def requestsSsVideoApi(ssid):
api = "https://api.bilibili.com/pgc/view/web/season?season_id="
response = requests.get(api + ssid).json()
if response["code"] == 0:
return response
def requestsMdVideoApi(mdid):
api = "https://api.bilibili.com/pgc/review/user?media_id="
response = requests.get(api + mdid).json()
if response["code"] == 0:
return response
def requestsAllVideoApi(ssid):
api = "https://api.bilibili.com/pgc/web/season/section?season_id="
response = requests.get(api + ssid).json()
if response["code"] == 0:
return response
def handleVideoBvResult(response_result):
"""根据BV号 判断是否有分P 是返回全部分P的信息 否返回该视频的封面"""
av = "av"
bilibili = "https://www.bilibili.com/"
ls = []
if response_result is not None:
if response_result.get("data").get("ugc_season") is not None:
if len(response_result.get("data").get("ugc_season").get("sections")) != 0:
for vds in response_result.get("data").get("ugc_season").get("sections"):
for vd in vds.get("episodes"):
vd_title = vd.get("title")
vd_cover = vd.get("arc").get("pic")
vd_bvid = vd.get("bvid")
vd_avid = vd.get("aid")
data = {
"title": vd_title,
"image": vd_cover,
"bvid": vd_bvid,
"avid": av + str(vd_avid),
"url": bilibili + vd_bvid,
}
ls.append(data)
return ls
else:
vd_data = response_result.get("data")
vd_title = vd_data.get("title")
vd_cover = vd_data.get("pic")
vd_bvid = vd_data.get("bvid")
vd_avid = vd_data.get("aid")
data = {
"title": vd_title,
"image": vd_cover,
"bvid": vd_bvid,
"avid": av + str(vd_avid),
"url": bilibili + vd_bvid,
}
return data
else:
return "Not"
def handleEpisodeResult(response_result, epid):
"""1.判断请求内容是否存在 2.判断番剧是否上线是继续判断是pv/小剧场还是番剧 否 判断是否为pv/小剧场"""
av = "av"
if response_result is not None:
if len(response_result.get("result").get("episodes")) != 0:
for eps in response_result.get("result").get("episodes"):
if eps.get("id") == int(epid):
ep_title = eps.get("share_copy")
ep_cover = eps.get("cover")
ep_bvid = eps.get("bvid")
ep_avid = eps.get("aid")
ep_url = eps.get("share_url")
data = {
"title": ep_title,
"image": ep_cover,
"bvid": ep_bvid,
"avid": av + str(ep_avid),
"url": ep_url,
}
return data
else:
if response_result.get("result").get("section") is not None:
if len(response_result.get("result").get("section")) != 0:
for pvs in response_result.get("result").get("section"):
for pv in (pvs.get("episodes")):
if pv.get("id") == int(epid):
ep_pv_title = pv.get("share_copy")
ep_pv_cover = pv.get("cover")
ep_pv_bvid = pv.get("bvid")
ep_pv_avid = pv.get("aid")
ep_pv_url = pv.get("share_url")
data = {
"title": ep_pv_title,
"image": ep_pv_cover,
"bvid": ep_pv_bvid,
"avid": av + str(ep_pv_avid),
"url": ep_pv_url,
}
return data
else:
for pvs in response_result.get("result").get("section"):
for pv in pvs.get("episodes"):
if pv.get("id") == int(epid):
ep_pv_title = pv.get("share_copy")
ep_pv_cover = pv.get("cover")
ep_pv_bvid = pv.get("bvid")
ep_pv_avid = pv.get("aid")
ep_pv_url = pv.get("share_url")
data = {
"title": ep_pv_title,
"image": ep_pv_cover,
"bvid": ep_pv_bvid,
"avid": av + str(ep_pv_avid),
"url": ep_pv_url,
}
return data
def handleSsResult(response_result, ssid):
av = "av"
if response_result is not None:
if len(response_result.get("result").get("episodes")) != 0:
if len(response_result.get("result").get("seasons")) != 0:
for sss in response_result.get("result").get("seasons"):
if sss.get("season_id") == int(ssid):
for eps in response_result.get("result").get("episodes"):
if sss.get("new_ep").get("id") == eps.get("id"):
ep_title = eps.get("share_copy")
ep_cover = eps.get("cover")
ep_bvid = eps.get("bvid")
ep_avid = eps.get("aid")
ep_url = eps.get("share_url")
data = {
"title": ep_title,
"image": ep_cover,
"bvid": ep_bvid,
"avid": av + str(ep_avid),
"url": ep_url,
}
return data
else:
return 404
def handleMdResult(response_result):
av = "av"
ep_ls = []
ep_pv_ls = []
if response_result is not None:
ssid = response_result.get("result").get("media").get("season_id")
title = response_result.get("result").get("media").get("title")
md_cover = response_result.get("result").get("media").get("cover")
md_url = response_result.get("result").get("media").get("share_url")
if requestsAllVideoApi(str(ssid)) is not None:
eps_data = requestsAllVideoApi(str(ssid))
if eps_data.get("result").get("main_section") is not None:
episodes_data = eps_data.get("result").get("main_section").get("episodes")
episodes_pv_data = eps_data.get("result").get("section")
if len(episodes_pv_data) != 0:
for eps_pv_data in episodes_pv_data:
for ep_pv_data in eps_pv_data.get("episodes"):
ep_pv_title = ep_pv_data.get("long_title")
if ep_pv_title == "":
ep_pv_title = ep_pv_data.get("title")
ep_pv_cover = ep_pv_data.get("cover")
ep_pv_url = ep_pv_data.get("share_url")
ep_pv_avid = ep_pv_data.get("aid")
ep_pv_bvid = biliBV.encode(ep_pv_avid)
ep_pv_dt = {
"title": ep_pv_title,
"image": ep_pv_cover,
"url": ep_pv_url,
"bvid": ep_pv_bvid,
"avid": av + str(ep_pv_avid),
}
ep_pv_ls.append(ep_pv_dt)
for ep_data in episodes_data:
ep_title = ep_data.get("long_title")
ep_cover = ep_data.get("cover")
ep_url = ep_data.get("share_url")
ep_avid = ep_data.get("aid")
ep_bvid = biliBV.encode(ep_avid)
ep_volume = ep_data.get("title")
ep_dt = {
"title": ep_title,
"image": ep_cover,
"url": ep_url,
"bvid": ep_bvid,
"avid": av + str(ep_avid),
"volume": ep_volume,
}
ep_ls.append(ep_dt)
data = {"title": title, "cover": md_cover, "url": md_url, "states": 1, "ep": ep_ls,
"pv": ep_pv_ls, }
return data
else:
for ep_data in episodes_data:
ep_title = ep_data.get("long_title")
ep_cover = ep_data.get("cover")
ep_url = ep_data.get("share_url")
ep_avid = ep_data.get("aid")
ep_bvid = biliBV.encode(ep_avid)
ep_volume = ep_data.get("title")
ep_dt = {
"title": ep_title,
"image": ep_cover,
"url": ep_url,
"bvid": ep_bvid,
"avid": av + str(ep_avid),
"volume": ep_volume,
}
ep_ls.append(ep_dt)
data = {"title": title, "cover": md_cover, "url": md_url, "states": 1, "ep": ep_ls}
return data
else:
episodes_pv_data = eps_data.get("result").get("section")
if len(episodes_pv_data) != 0:
for eps_pv_data in episodes_pv_data:
for ep_pv_data in eps_pv_data.get("episodes"):
ep_pv_title = ep_pv_data.get("long_title")
if ep_pv_title == "":
ep_pv_title = ep_pv_data.get("title")
ep_pv_cover = ep_pv_data.get("cover")
ep_pv_url = ep_pv_data.get("share_url")
ep_pv_avid = ep_pv_data.get("aid")
ep_pv_bvid = biliBV.encode(ep_pv_avid)
ep_pv_dt = {
"title": ep_pv_title,
"image": ep_pv_cover,
"url": ep_pv_url,
"bvid": ep_pv_bvid,
"avid": av + str(ep_pv_avid),
}
ep_pv_ls.append(ep_pv_dt)
data = {"title": title, "cover": md_cover, "url": md_url, "states": 0, "pv": ep_pv_ls}
return data
def main(content):
"""入口"""
data = handleUrl(content)
if data is not None:
if regexBv(data) is not None:
bvid = regexBv(data)
if requestsBvVideoApi(bvid) is not None:
result = requestsBvVideoApi(bvid)
print(f"获取成功.bv号: {bvid}")
return handleVideoBvResult(result)
elif regexAv(data) is not None:
bvid = regexAv(data)
if requestsBvVideoApi(bvid) is not None:
result = requestsBvVideoApi(bvid)
av = biliBV.decode(bvid)
print(f"获取成功.av号: {av}")
return handleVideoBvResult(result)
elif regexEp(data) is not None:
epid = regexEp(data)
if requestsEpVideoApi(epid) is not None:
result = requestsEpVideoApi(epid)
print(f"获取成功.ep号: {epid}")
return handleEpisodeResult(result, epid)
elif regexSs(data) is not None:
ssid = regexSs(data)
result = requestsSsVideoApi(ssid)
print(f"获取成功.ss号: {ssid}")
return handleSsResult(result, ssid)
elif regexMd(data) is not None:
mdid = regexMd(data)
result = requestsMdVideoApi(mdid)
print(f"获取成功.md号: {mdid}")
return handleMdResult(result)
else:
if regexBv(content) is not None:
bvid = regexBv(content)
if requestsBvVideoApi(bvid) is not None:
result = requestsBvVideoApi(bvid)
print(f"获取成功.bv号: {bvid}")
return handleVideoBvResult(result)
elif regexAv(content) is not None:
bvid = regexAv(content)
if requestsBvVideoApi(bvid) is not None:
result = requestsBvVideoApi(bvid)
av = biliBV.decode(bvid)
print(f"获取成功.av号: {av}")
return handleVideoBvResult(result)
elif regexEp(content) is not None:
epid = regexEp(content)
if requestsEpVideoApi(epid) is not None:
result = requestsEpVideoApi(epid)
print(f"获取成功.ep号: {epid}")
return handleEpisodeResult(result, epid)
elif regexSs(content) is not None:
ssid = regexSs(content)
if requestsSsVideoApi(ssid) is not None:
result = requestsSsVideoApi(ssid)
print(f"获取成功.ss号: {ssid}")
return handleSsResult(result, ssid)
elif regexMd(content) is not None:
mdid = regexMd(content)
if requestsMdVideoApi(mdid) is not None:
result = requestsMdVideoApi(mdid)
print(f"获取成功.md号: {mdid}")
return handleMdResult(result)
if __name__ == '__main__':
bv1 = "https://www.bilibili.com/video/BV1wu411B7rA?spm_id_from=333.851.b_7265636f6d6d656e64.1"# bv 多p
result = main(bv1)
# 视频多P
if isinstance(result, list):
for vd in result:
print(f"标题: {vd['title']} 封面: {vd['image']} av号: {vd['avid']} bv号: {vd['bvid']} 视频地址: {vd['url']}")
elif isinstance(result, dict):
# states = 1 上线 states = 0 没上线
if result.get("states") == 1:
# 番剧上线了 有ep 有pv
if result.get("ep") is not None and result.get("pv") is not None:
print(f"番剧名: {result['title']} 海报: {result['cover']} 番剧地址: {result['url']}")
for ep in result.get("ep"):
print(
f"剧集: 第{ep['volume']}话 标题: {ep['title']} 封面: {ep['image']} av号: {ep['avid']} bv号: {ep['bvid']} 剧集地址: {ep['url']}")
for pv in result.get("pv"):
print(f"标题: {pv['title']} 封面: {pv['image']} av号: {pv['avid']} bv号: {pv['bvid']} 剧集地址: {pv['url']}")
# 番剧上线了 有ep 没有pv
else:
print(f"番剧名: {result['title']} 海报: {result['cover']} 番剧地址: {result['url']}")
for ep in result.get("ep"):
print(
f"剧集: 第{ep['volume']}话 标题: {ep['title']} 封面: {ep['image']} av号: {ep['avid']} bv号: {ep['bvid']} 剧集地址: {ep['url']}")
# 番剧没上线 只有pv
elif result.get("states") == 0:
print(f"番剧名: {result['title']} 海报: {result['cover']} 番剧地址: {result['url']}")
for pv in result.get("pv"):
print(f"标题: {pv['title']} 封面: {pv['image']} av号: {pv['avid']} bv号: {pv['bvid']} 剧集地址: {pv['url']}")
else:
# 视频单P
print(
f"标题: {result['title']} 封面: {result['image']} av号: {result['avid']} bv号: {result['bvid']} 视频地址: {result['url']}")
else:
print("请检查是否输错了呀, 注意:没上线的番 用ss链接无法获取哦")
https://github.com/Smalltred/BilibiliCover
附件:
大佬NB,我收下了{:1_893:} 学习下,感谢分享。 感谢分享,收藏啦
感谢分享 学习一下,感谢分享 主要是抓包后分析链接麻烦啊,楼主好有耐心 感谢分享 楼主nb。之前一直用的一个是链接。你这个更方便。
页:
[1]
2