zhenxun_bot/plugins/parse_bilibili_json.py

171 lines
7.1 KiB
Python
Raw Normal View History

2022-06-21 08:50:05 +08:00
from nonebot import on_message
from services.log import logger
from nonebot.adapters.onebot.v11 import GroupMessageEvent, ActionFailed
2022-09-27 03:11:57 +08:00
from utils.manager import group_manager
2022-06-21 08:50:05 +08:00
from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text
from nonebot.adapters.onebot.v11.permission import GROUP
from utils.message_builder import image
from utils.image_utils import BuildImage
from utils.browser import get_browser
from configs.path_config import IMAGE_PATH
from utils.http_utils import AsyncHttpx
from configs.config import Config
from utils.user_agent import get_user_agent
import aiohttp
import asyncio
import time
import ujson as json
from bilireq import video
__zx_plugin_name__ = "B站转发解析"
__plugin_usage__ = """
usage
B站转发解析解析b站分享信息支持bvbilibili链接b站手机端转发卡片cvb23.tv且5分钟内不解析相同url
""".strip()
__plugin_des__ = "B站转发解析"
__plugin_type__ = ("其他",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_task__ = {"bilibili_parse": "b站转发解析"}
Config.add_plugin_config(
"_task",
"DEFAULT_BILIBILI_PARSE",
True,
help_="被动 B站转发解析 进群默认开关状态",
default_value=True,
)
2022-09-27 03:11:57 +08:00
async def plugin_on_checker(event: GroupMessageEvent) -> bool:
return group_manager.get_plugin_status("parse_bilibili_json", event.group_id)
parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False, rule=plugin_on_checker)
2022-06-21 08:50:05 +08:00
_tmp = {}
@parse_bilibili_json.handle()
async def _(event: GroupMessageEvent):
vd_info = None
url = None
if get_message_json(event.json()):
try:
data = json.loads(get_message_json(event.json())[0]["data"])
except (IndexError, KeyError):
data = None
if data:
# 转发视频
修复B站转发卡片BUG 1. 最新URL `https://b23.tv/nz4tMtX` 返回 ``` HTTP/2 301 date: Tue, 31 Jan 2023 09:43:07 GMT content-type: text/html; charset=utf-8 content-length: 781 set-cookie: ******; path=/; expires=Mon, 27 Oct 2025 09:43:07 GMT; domain=.bilibili.com set-cookie: b_nut=1675158187; path=/; expires=Wed, 31 Jan 2024 09:43:07 GMT; domain=.bilibili.com location: /video/BV1CM4y197A4/?buvid=****** vary: Origin,Accept-Encoding idc: shjd x-cache-webcdn: BYPASS from blzone07 ``` 这时候 url 会变成 `/video/BV1CM4y197A4/` 需要去除末尾的/来提取BVID 2. 某些转发(比如ios客户端)目前QQ小程序的desc为空,需要在prompt里检测 ```json [CQ:json,data={"app":"com.tencent.miniapp_01","appID":"100951776","bthirdappforward":true,"bthirdappforwardforbackendswitch":true,"config":{"autoSize":0,"ctime":1675159871,"forward":1,"height":0,"token":"d1dda06f69b12d511972e87ec49b2a19","type":"normal","width":0},"desc":"","extra":{"app_type":1,"appid":100951776,"uin":28696786},"meta":{"detail_1":{"appType":0,"appid":"1109937557","desc":"网络中挖到国防光缆vs现实","gamePoints":"","gamePointsUrl":"","host":{"nick":"Noahzark","uin":28696786},"icon":"http://miniapp.gtimg.cn/public/appicon/432b76be3a548fc128acaa6c1ec90131_200.jpg","preview":"https://pic.ugcimg.cn/07cc5adddb5e6ef3cc27326a12b2df17/jpg1","qqdocurl":"https://b23.tv/******","scene":1036,"shareTemplateData":{},"shareTemplateId":"8C8E89B49BE609866298ADDFF2DBABA4","showLittleTail":"","title":"哔哩哔哩","url":"m.q.qq.com/a/s/f6362a996fd107b3d4dbedce09c17d92"}},"prompt":"[QQ小程序]哔哩哔哩","ver":"1.0.1.42","view":"view_8C8E89B49BE609866298ADDFF2DBABA4"}] ```
2023-01-31 18:13:52 +08:00
if data.get("desc") == "哔哩哔哩" or data.get('prompt').find('哔哩哔哩') != -1:
2022-06-21 08:50:05 +08:00
async with aiohttp.ClientSession(
headers=get_user_agent()
) as session:
async with session.get(
data["meta"]["detail_1"]["qqdocurl"],
timeout=7,
) as response:
url = str(response.url).split("?")[0]
修复B站转发卡片BUG 1. 最新URL `https://b23.tv/nz4tMtX` 返回 ``` HTTP/2 301 date: Tue, 31 Jan 2023 09:43:07 GMT content-type: text/html; charset=utf-8 content-length: 781 set-cookie: ******; path=/; expires=Mon, 27 Oct 2025 09:43:07 GMT; domain=.bilibili.com set-cookie: b_nut=1675158187; path=/; expires=Wed, 31 Jan 2024 09:43:07 GMT; domain=.bilibili.com location: /video/BV1CM4y197A4/?buvid=****** vary: Origin,Accept-Encoding idc: shjd x-cache-webcdn: BYPASS from blzone07 ``` 这时候 url 会变成 `/video/BV1CM4y197A4/` 需要去除末尾的/来提取BVID 2. 某些转发(比如ios客户端)目前QQ小程序的desc为空,需要在prompt里检测 ```json [CQ:json,data={"app":"com.tencent.miniapp_01","appID":"100951776","bthirdappforward":true,"bthirdappforwardforbackendswitch":true,"config":{"autoSize":0,"ctime":1675159871,"forward":1,"height":0,"token":"d1dda06f69b12d511972e87ec49b2a19","type":"normal","width":0},"desc":"","extra":{"app_type":1,"appid":100951776,"uin":28696786},"meta":{"detail_1":{"appType":0,"appid":"1109937557","desc":"网络中挖到国防光缆vs现实","gamePoints":"","gamePointsUrl":"","host":{"nick":"Noahzark","uin":28696786},"icon":"http://miniapp.gtimg.cn/public/appicon/432b76be3a548fc128acaa6c1ec90131_200.jpg","preview":"https://pic.ugcimg.cn/07cc5adddb5e6ef3cc27326a12b2df17/jpg1","qqdocurl":"https://b23.tv/******","scene":1036,"shareTemplateData":{},"shareTemplateId":"8C8E89B49BE609866298ADDFF2DBABA4","showLittleTail":"","title":"哔哩哔哩","url":"m.q.qq.com/a/s/f6362a996fd107b3d4dbedce09c17d92"}},"prompt":"[QQ小程序]哔哩哔哩","ver":"1.0.1.42","view":"view_8C8E89B49BE609866298ADDFF2DBABA4"}] ```
2023-01-31 18:13:52 +08:00
if url[-1] == '/':
url = url[:-1]
2022-06-21 08:50:05 +08:00
bvid = url.split("/")[-1]
vd_info = await video.get_video_base_info(bvid)
# 转发专栏
if (
data.get("meta")
and data["meta"].get("news")
and data["meta"]["news"].get("desc") == "哔哩哔哩专栏"
):
url = data["meta"]["news"]["jumpUrl"]
page = None
try:
browser = await get_browser()
if not browser:
return
page = await browser.new_page(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
" (KHTML, like Gecko) Chrome/93.0.4530.0 Safari/537.36"
)
await page.goto(url, wait_until="networkidle", timeout=10000)
await page.set_viewport_size({"width": 2560, "height": 1080})
await page.click("#app > div")
div = await page.query_selector("#app > div")
await div.screenshot(
path=f"{IMAGE_PATH}/temp/cv_{event.user_id}.png",
timeout=100000,
)
await asyncio.get_event_loop().run_in_executor(
None, resize, f"{IMAGE_PATH}/temp/cv_{event.user_id}.png"
)
await parse_bilibili_json.send(
"[[_task|bilibili_parse]]" + image(f"cv_{event.user_id}.png", "temp")
)
await page.close()
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}"
)
except Exception as e:
logger.error(f"尝试解析bilibili专栏 {url} 失败 {type(e)}{e}")
if page:
await page.close()
return
# BV
if msg := get_message_text(event.json()):
if "BV" in msg:
index = msg.find("BV")
if len(msg[index + 2 :]) >= 10:
msg = msg[index : index + 12]
url = f"https://www.bilibili.com/video/{msg}"
vd_info = await video.get_video_base_info(msg)
elif "av" in msg:
index = msg.find("av")
2022-08-23 13:43:43 +08:00
if len(msg[index + 2 :]) >= 1:
2022-06-21 08:50:05 +08:00
msg = msg[index + 2 : index + 11]
if is_number(msg):
2022-08-23 13:43:43 +08:00
url = f"https://www.bilibili.com/video/av{msg}"
2022-08-21 13:37:03 +08:00
vd_info = await video.get_video_base_info('av' + msg)
2022-06-21 08:50:05 +08:00
elif "https://b23.tv" in msg:
2022-07-16 05:48:00 +08:00
url = "https://" + msg[msg.find("b23.tv"): msg.find("b23.tv") + 14]
async with aiohttp.ClientSession(
headers=get_user_agent()
) as session:
async with session.get(
url,
timeout=7,
) as response:
2022-09-27 03:11:57 +08:00
url = (str(response.url).split("?")[0]).strip("/")
2022-07-16 05:48:00 +08:00
bvid = url.split("/")[-1]
vd_info = await video.get_video_base_info(bvid)
2022-06-21 08:50:05 +08:00
if vd_info:
if (
url in _tmp.keys() and time.time() - _tmp[url] > 30
) or url not in _tmp.keys():
_tmp[url] = time.time()
aid = vd_info["aid"]
title = vd_info["title"]
author = vd_info["owner"]["name"]
reply = vd_info["stat"]["reply"] # 回复
favorite = vd_info["stat"]["favorite"] # 收藏
coin = vd_info["stat"]["coin"] # 投币
# like = vd_info['stat']['like'] # 点赞
# danmu = vd_info['stat']['danmaku'] # 弹幕
date = time.strftime("%Y-%m-%d", time.localtime(vd_info["ctime"]))
try:
await parse_bilibili_json.send(
"[[_task|bilibili_parse]]" +
image(vd_info["pic"]) + f"\nav{aid}\n标题:{title}\n"
f"UP{author}\n"
f"上传日期:{date}\n"
f"回复:{reply},收藏:{favorite},投币:{coin}\n"
f"{url}"
)
except ActionFailed:
logger.warning(f"{event.group_id} 发送bilibili解析失败")
else:
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}"
)
def resize(path: str):
A = BuildImage(0, 0, background=path, ratio=0.5)
A.save(path)