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)}")