Files
Agent-Reach/x_reader/fetchers/bilibili.py
T

47 lines
1.4 KiB
Python

# -*- coding: utf-8 -*-
"""Bilibili video fetcher — uses official web API."""
import re
import requests
from loguru import logger
from typing import Dict, Any
API_URL = "https://api.bilibili.com/x/web-interface/view"
HEADERS = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
}
async def fetch_bilibili(url_or_bv: str) -> Dict[str, Any]:
"""Fetch Bilibili video metadata via official API."""
logger.info(f"Fetching Bilibili: {url_or_bv}")
bv_id = url_or_bv
if "bilibili.com" in url_or_bv or "b23.tv" in url_or_bv:
match = re.search(r'BV\w+', url_or_bv)
if match:
bv_id = match.group()
else:
raise ValueError(f"Cannot extract BV ID from: {url_or_bv}")
resp = requests.get(API_URL, params={"bvid": bv_id}, headers=HEADERS, timeout=10)
resp.raise_for_status()
data = resp.json()
if data.get("code") != 0:
raise ValueError(f"Bilibili API error: {data.get('message')}")
video = data["data"]
return {
"title": video.get("title", ""),
"description": video.get("desc", ""),
"author": video.get("owner", {}).get("name", ""),
"url": f"https://www.bilibili.com/video/{bv_id}",
"cover": video.get("pic", ""),
"bvid": bv_id,
"duration": video.get("duration", 0),
"view_count": video.get("stat", {}).get("view", 0),
"platform": "bilibili",
}