This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
openclaw-skills/skills/kb-workflow/src/sources/zhihu.py
T

92 lines
2.8 KiB
Python

"""Obsidian KB - 知乎源"""
import re
from typing import Optional
from .base import BaseSource
from ..models import Content, ContentType
try:
from .zhihu_drission_extractor import ZhihuDrissionExtractor
except ImportError:
# DrissionPage 未安装
import logging
logger = logging.getLogger(__name__)
logger.warning(f"DrissionPage 未安装,无法提取知乎内容")
class ZhihuSource(BaseSource):
"""知乎文章/回答源"""
name = "zhihu"
URL_PATTERNS = [
r'zhihu\.com/question/\d+/answer/(\d+)',
r'zhuanlan\.zhihu\.com/p/(\d+)',
r'zhihu\.com/question/(\d+)',
]
def can_handle(self, url: str) -> bool:
"""检查是否为知乎链接"""
return 'zhihu.com' in url or 'zhuanlan.zhihu.com' in url
def extract_id(self, url: str) -> Optional[str]:
"""提取内容ID"""
for pattern in self.URL_PATTERNS:
match = re.search(pattern, url)
if match:
return match.group(1)
return None
def fetch(self, url: str) -> Optional[Content]:
"""获取内容元数据"""
content_id = self.extract_id(url)
if not content_id:
return None
# TODO: 使用知乎API或爬虫获取完整信息
content_type = ContentType.ARTICLE
if 'zhuanlan' in url:
content_type = ContentType.ARTICLE
return Content(
source=self.name,
source_id=content_id,
url=url,
title='',
author='',
content_type=content_type
)
def get_transcript(self, content: Content) -> Optional[str]:
"""获取文章内容"""
try:
# 使用 DrissionPage 提取器
extractor = ZhihuDrissionExtractor(
headless=self.config.get('headless', True),
timeout=self.config.get('timeout', 30),
config=self.config
)
data = extractor.extract(content.url)
if data and data.get('content_markdown'):
# 更新元数据
if data.get('title'):
content.title = data['title']
if data.get('author'):
content.author = data['author']
# 返回 Markdown 内容
return data['content_markdown']
except ImportError as e:
import logging
logger = logging.getLogger(__name__)
logger.error(f"DrissionPage 导入失败: {e}")
except Exception as e:
import logging
logger = logging.getLogger(__name__)
logger.error(f"DrissionPage 提取失败: {e}")
return None