#!/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()