121 lines
4.8 KiB
Python
121 lines
4.8 KiB
Python
from parsers.base import BaseParser
|
||
from typing import Dict
|
||
from urllib.parse import urlencode
|
||
|
||
class BilibiliMirParser(BaseParser):
|
||
"""哔哩哔哩解析器 - 米人API"""
|
||
|
||
def parse(self, video_url: str) -> Dict:
|
||
"""解析哔哩哔哩视频"""
|
||
try:
|
||
# 手动构建URL,避免双重编码
|
||
url = f"{self.api_url}/api/bzjiexi?{urlencode({'url': video_url})}"
|
||
|
||
response = self._make_request(url)
|
||
data = response.json()
|
||
|
||
return self._extract_data(data)
|
||
except Exception as e:
|
||
raise Exception(f"哔哩哔哩解析失败(米人API): {str(e)}")
|
||
|
||
def _extract_data(self, data: Dict) -> Dict:
|
||
"""提取并标准化数据"""
|
||
try:
|
||
if data.get("code") == 200 or data.get("status") == "success":
|
||
video_data = data.get("data", {})
|
||
|
||
# 如果data是列表,取第一个元素
|
||
if isinstance(video_data, list):
|
||
video_data = video_data[0] if video_data else {}
|
||
|
||
cover = video_data.get("cover", "") or video_data.get("pic", "")
|
||
video_url = video_data.get("url", "") or video_data.get("video_url", "")
|
||
title = video_data.get("title", "")
|
||
description = video_data.get("desc", "") or video_data.get("description", "")
|
||
|
||
return self._normalize_response(cover, video_url, title, description)
|
||
else:
|
||
raise Exception(f"解析失败: {data.get('msg', '未知错误')}")
|
||
except Exception as e:
|
||
raise Exception(f"数据提取失败: {str(e)}")
|
||
|
||
|
||
class BilibiliBugPKParser(BaseParser):
|
||
"""哔哩哔哩解析器 - BugPK API"""
|
||
|
||
def parse(self, video_url: str) -> Dict:
|
||
"""解析哔哩哔哩视频"""
|
||
try:
|
||
# 手动构建URL,避免双重编码
|
||
url = f"{self.api_url}/api/bilibili?{urlencode({'url': video_url})}"
|
||
|
||
response = self._make_request(url)
|
||
data = response.json()
|
||
|
||
return self._extract_data(data)
|
||
except Exception as e:
|
||
raise Exception(f"哔哩哔哩解析失败(BugPK API): {str(e)}")
|
||
|
||
def _extract_data(self, data: Dict) -> Dict:
|
||
"""提取并标准化数据"""
|
||
try:
|
||
if data.get("code") == 200 or data.get("status") == "success":
|
||
video_data = data.get("data", {})
|
||
|
||
# 如果data是列表,取第一个元素
|
||
if isinstance(video_data, list):
|
||
video_data = video_data[0] if video_data else {}
|
||
|
||
cover = video_data.get("cover", "") or video_data.get("pic", "")
|
||
video_url = video_data.get("url", "") or video_data.get("video_url", "")
|
||
title = video_data.get("title", "")
|
||
description = video_data.get("desc", "") or video_data.get("description", "")
|
||
|
||
return self._normalize_response(cover, video_url, title, description)
|
||
else:
|
||
raise Exception(f"解析失败: {data.get('msg', '未知错误')}")
|
||
except Exception as e:
|
||
raise Exception(f"数据提取失败: {str(e)}")
|
||
|
||
|
||
class BilibiliYaohuParser(BaseParser):
|
||
"""哔哩哔哩解析器 - 妖狐API"""
|
||
|
||
def parse(self, video_url: str) -> Dict:
|
||
"""解析哔哩哔哩视频"""
|
||
try:
|
||
# 手动构建URL,避免双重编码
|
||
url = f"{self.api_url}/api/v6/video/bili?{urlencode({'key': self.api_key, 'url': video_url})}"
|
||
|
||
response = self._make_request(url, verify=False)
|
||
data = response.json()
|
||
|
||
return self._extract_data(data)
|
||
except Exception as e:
|
||
raise Exception(f"哔哩哔哩解析失败(妖狐API): {str(e)}")
|
||
|
||
def _extract_data(self, data: Dict) -> Dict:
|
||
"""提取并标准化数据"""
|
||
try:
|
||
if data.get("parse_type") == "video":
|
||
video_data = data.get("data", {})
|
||
basic = video_data.get("basic", {})
|
||
|
||
# 提取基本信息
|
||
cover = basic.get("cover", "")
|
||
title = basic.get("title", "")
|
||
description = basic.get("description", "")
|
||
|
||
# 提取视频URL - 优先使用data.video_url,其次使用videos[0].url
|
||
video_url = video_data.get("video_url", "")
|
||
if not video_url:
|
||
videos = video_data.get("videos", [])
|
||
if isinstance(videos, list) and videos:
|
||
video_url = videos[0].get("url", "")
|
||
|
||
return self._normalize_response(cover, video_url, title, description)
|
||
else:
|
||
raise Exception(f"解析失败: 不支持的类型 {data.get('parse_type')}")
|
||
except Exception as e:
|
||
raise Exception(f"数据提取失败: {str(e)}")
|