吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2834|回复: 14
收起左侧

[Python 转载] 一个获取B站视频封面的小工具

[复制链接]
Traitor 发表于 2022-3-27 18:29
本帖最后由 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 修改了输出内容的逻辑让代码看起来不是那么复杂

[Python] 纯文本查看 复制代码
#!/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"[a-zA-z]+://[^\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)[2:]


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)[2:]
            result = requestsSsVideoApi(ssid)
            print(f"获取成功.ss号: {ssid}")
            return handleSsResult(result, ssid)
        elif regexMd(data) is not None:
            mdid = regexMd(data)[2:]
            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)[2:]
            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)[2:]
            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

附件: UserBilibiliCover.zip (3.08 KB, 下载次数: 23)


免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
sushaka + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ACTEN20645 发表于 2022-3-27 18:44
大佬NB,我收下了
雾都孤尔 发表于 2022-3-27 19:04
i2080 发表于 2022-3-27 19:27
iooioox 发表于 2022-3-27 19:34

感谢分享
haihua301 发表于 2022-3-27 20:15
学习一下,感谢分享
头像被屏蔽
xiadongming 发表于 2022-3-27 20:25
提示: 作者被禁止或删除 内容自动屏蔽
1024A1024 发表于 2022-3-27 20:48
主要是抓包后分析链接麻烦啊,楼主好有耐心
imeh 发表于 2022-3-27 21:28
感谢分享
p1142619270 发表于 2022-3-28 08:38
楼主nb。之前一直用的一个是链接。你这个更方便。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-7 21:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表