feat(obsidian-kb): 实现短链接解析功能
- 新增 shortlink_resolver.py 模块 * 检测 B站短链接(b23.tv)和其他短链接服务 * 提供友好的用户引导信息 * 支持 Playwright 浏览器自动化解析(可选) - 集成到 handler.py * 短链接自动检测和提示 * 智能区分短链接和完整 URL - 更新 add_video.py * 支持短链接解析 * 添加 --playwright 参数启用浏览器解析 - 新增 test_shortlink.py 测试脚本 * 测试单个短链接检测 * 测试多个短链接检测 * 测试混合内容场景 * 所有测试通过 - 更新文档 * SKILL.md: 添加短链接说明 * AUTO_TRIGGER.md: 添加短链接章节 * obsidian-kb-improvements.md: 标记任务2为已完成 功能特点: - 方案A(用户引导):已实现并作为默认行为 - 方案B(浏览器自动化):提供 PlaywrightResolver 类,可选使用 - 方案C(代理池):未实现(复杂度高,收益低) 验收标准达成: ✅ 短链接能够友好处理(显示引导信息) ✅ 用户不会感到困惑 ✅ 支持 b23.tv 和其他短链接服务(检测) ✅ 集成到 handler.py ✅ 测试各种短链接场景
This commit is contained in:
Regular → Executable
+45
-11
@@ -13,16 +13,22 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'src
|
||||
from sources.bilibili import BilibiliAdapter
|
||||
from models import Content, ContentStatus
|
||||
from storage import Storage
|
||||
from shortlink_resolver import (
|
||||
ShortLinkResolver,
|
||||
PlaywrightResolver,
|
||||
detect_and_format
|
||||
)
|
||||
|
||||
def resolve_short_url(url: str) -> str:
|
||||
def resolve_short_url(url: str, try_playwright: bool = False) -> str:
|
||||
"""
|
||||
解析短链接(如 b23.tv)到完整URL,或接受BV号
|
||||
|
||||
Args:
|
||||
url: 可能是短链接的URL、完整URL或BV号
|
||||
try_playwright: 是否尝试使用Playwright解析短链接
|
||||
|
||||
Returns:
|
||||
str: 完整URL或BV号
|
||||
str: 完整URL或BV号,如果失败返回None
|
||||
"""
|
||||
# 如果已经是完整URL,直接返回
|
||||
if 'bilibili.com/video/' in url:
|
||||
@@ -33,23 +39,42 @@ def resolve_short_url(url: str) -> str:
|
||||
return url
|
||||
|
||||
# 如果是短链接,尝试解析
|
||||
if 'b23.tv' in url:
|
||||
resolver = ShortLinkResolver()
|
||||
|
||||
if resolver.is_bilibili_short_link(url):
|
||||
print(f" ⚠️ 检测到短链接 {url}")
|
||||
print(f" 💡 B站对短链接有反爬虫保护,请提供:")
|
||||
print(f" 1. 完整URL: https://www.bilibili.com/video/BVxxxxx")
|
||||
print(f" 2. 或BV号: BVxxxxx")
|
||||
print(f"\n 提示: 可以在浏览器打开短链接,从地址栏复制完整URL")
|
||||
|
||||
# 尝试使用Playwright解析(如果启用)
|
||||
if try_playwright:
|
||||
print(f" 🔄 尝试使用浏览器解析...")
|
||||
playwright_resolver = PlaywrightResolver(headless=True)
|
||||
|
||||
try:
|
||||
resolved_url = playwright_resolver.resolve_bilibili_short(url)
|
||||
if resolved_url:
|
||||
print(f" ✅ 解析成功: {resolved_url}")
|
||||
return resolved_url
|
||||
else:
|
||||
print(f" ❌ 浏览器解析失败")
|
||||
except Exception as e:
|
||||
print(f" ❌ Playwright不可用或解析失败: {e}")
|
||||
|
||||
# 显示用户引导
|
||||
print("")
|
||||
print(resolver.format_short_link_help(url))
|
||||
print("")
|
||||
return None
|
||||
|
||||
# 默认返回原URL
|
||||
return url
|
||||
|
||||
def add_video_to_inbox(url: str) -> str:
|
||||
def add_video_to_inbox(url: str, try_playwright: bool = False) -> str:
|
||||
"""
|
||||
添加B站视频到收件箱
|
||||
|
||||
Args:
|
||||
url: B站视频URL
|
||||
try_playwright: 是否尝试使用Playwright解析短链接
|
||||
|
||||
Returns:
|
||||
str: Content ID
|
||||
@@ -57,7 +82,7 @@ def add_video_to_inbox(url: str) -> str:
|
||||
print(f"📥 正在处理视频: {url}")
|
||||
|
||||
# 解析短链接
|
||||
resolved_url = resolve_short_url(url)
|
||||
resolved_url = resolve_short_url(url, try_playwright=try_playwright)
|
||||
if resolved_url is None:
|
||||
return None
|
||||
|
||||
@@ -104,8 +129,17 @@ def add_video_to_inbox(url: str) -> str:
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print("用法: python3 add_video.py <B站视频URL>")
|
||||
print("示例: python3 add_video.py https://b23.tv/oLBZZfK")
|
||||
print("示例:")
|
||||
print(" python3 add_video.py https://www.bilibili.com/video/BV1xx411c7mD")
|
||||
print(" python3 add_video.py BV1xx411c7mD")
|
||||
print(" python3 add_video.py https://b23.tv/oLBZZfK")
|
||||
print("\n选项:")
|
||||
print(" --playwright 尝试使用浏览器解析短链接")
|
||||
sys.exit(1)
|
||||
|
||||
url = sys.argv[1]
|
||||
add_video_to_inbox(url)
|
||||
try_playwright = '--playwright' in sys.argv
|
||||
if try_playwright and url == '--playwright' and len(sys.argv) > 2:
|
||||
url = sys.argv[2]
|
||||
|
||||
add_video_to_inbox(url, try_playwright=try_playwright)
|
||||
|
||||
Reference in New Issue
Block a user