56907e31f5
- Remove question, answer, user types (not needed for knowledge base) - Keep only zvideo (知乎视频) and zhuanlan (知乎专栏文章) - Update URL patterns and extraction logic - Simplified CLI interface
154 lines
4.0 KiB
Python
154 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
知乎元数据获取工具
|
|
|
|
仅支持两种内容类型:
|
|
- zvideo: 知乎视频 (https://www.zhihu.com/zvideo/xxx)
|
|
- zhuanlan: 知乎专栏文章 (https://zhuanlan.zhihu.com/p/xxx)
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
import os
|
|
from typing import Dict, Optional, Any
|
|
|
|
# 添加当前目录到 Python 路径
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
if current_dir not in sys.path:
|
|
sys.path.insert(0, current_dir)
|
|
|
|
from zhihu_extractor import ZhihuPlaywrightExtractor
|
|
|
|
|
|
def extract_zvideo(video_id: str, headless: bool = True) -> Dict[str, Any]:
|
|
"""
|
|
获取知乎视频元数据
|
|
|
|
Args:
|
|
video_id: 视频 ID (数字字符串)
|
|
headless: 是否使用无头浏览器
|
|
|
|
Returns:
|
|
视频元数据字典
|
|
"""
|
|
url = f"https://www.zhihu.com/zvideo/{video_id}"
|
|
return _extract_metadata(url, "zvideo", headless)
|
|
|
|
|
|
def extract_zhuanlan(article_id: str, headless: bool = True) -> Dict[str, Any]:
|
|
"""
|
|
获取知乎专栏文章元数据
|
|
|
|
Args:
|
|
article_id: 文章 ID (数字字符串)
|
|
headless: 是否使用无头浏览器
|
|
|
|
Returns:
|
|
文章元数据字典
|
|
"""
|
|
url = f"https://zhuanlan.zhihu.com/p/{article_id}"
|
|
return _extract_metadata(url, "zhuanlan", headless)
|
|
|
|
|
|
def _extract_metadata(url: str, content_type: str, headless: bool) -> Dict[str, Any]:
|
|
"""
|
|
内部函数:提取元数据
|
|
|
|
Args:
|
|
url: 知乎 URL
|
|
content_type: 内容类型 (zvideo/zhuanlan)
|
|
headless: 是否使用无头浏览器
|
|
|
|
Returns:
|
|
元数据字典
|
|
"""
|
|
extractor = ZhihuPlaywrightExtractor(headless=headless)
|
|
result = extractor.extract(url)
|
|
|
|
if result:
|
|
# 标准化输出格式
|
|
metadata = {
|
|
"type": content_type,
|
|
"id": result.get("content_id", ""),
|
|
"url": result.get("url", url),
|
|
"title": result.get("title", ""),
|
|
"author": result.get("author", ""),
|
|
"publish_time": result.get("publish_time", ""),
|
|
"vote_up": result.get("vote_up", 0),
|
|
"content_markdown": result.get("content_markdown", ""),
|
|
"raw_html": result.get("content", ""),
|
|
}
|
|
return metadata
|
|
else:
|
|
return {
|
|
"type": content_type,
|
|
"error": "Failed to extract content",
|
|
"url": url
|
|
}
|
|
|
|
|
|
def main():
|
|
"""命令行入口"""
|
|
parser = argparse.ArgumentParser(
|
|
description="知乎元数据获取工具",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog="""
|
|
支持的类型:
|
|
zvideo - 知乎视频 (https://www.zhihu.com/zvideo/123456)
|
|
zhuanlan - 知乎专栏文章 (https://zhuanlan.zhihu.com/p/123456)
|
|
|
|
示例:
|
|
python zhihu_metadata.py --id "123456" --type zvideo
|
|
python zhihu_metadata.py --id "123456" --type zhuanlan
|
|
"""
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--id", "-i",
|
|
required=True,
|
|
help="知乎内容 ID (视频ID或文章ID)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--type", "-t",
|
|
required=True,
|
|
choices=["zvideo", "zhuanlan"],
|
|
help="内容类型: zvideo=视频, zhuanlan=专栏文章"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--output", "-o",
|
|
default=None,
|
|
help="输出文件路径 (默认: stdout)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--headless",
|
|
action="store_true",
|
|
default=True,
|
|
help="使用无头浏览器模式 (默认: True)"
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# 提取元数据
|
|
if args.type == "zvideo":
|
|
result = extract_zvideo(args.id, headless=args.headless)
|
|
else: # zhuanlan
|
|
result = extract_zhuanlan(args.id, headless=args.headless)
|
|
|
|
# 输出结果
|
|
json_output = json.dumps(result, ensure_ascii=False, indent=2)
|
|
|
|
if args.output:
|
|
with open(args.output, 'w', encoding='utf-8') as f:
|
|
f.write(json_output)
|
|
print(f"结果已保存到: {args.output}")
|
|
else:
|
|
print(json_output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|