#!/usr/bin/env python3 """ 小红书热点趋势工作流主模块 整合热点发现、AI创作、发布全流程 """ import os import sys import json import argparse from datetime import datetime from typing import Optional # 导入子模块 from topic_discovery import TopicDiscovery from content_generator import ContentGenerator from publisher_adapter import XHSPublisherAdapter class XHSTrendingWorkflow: """ 小红书热点趋势工作流 完整流程: 1. 搜索热门话题 2. AI创作原创内容 3. 去AI化处理 4. 发布到小红书 """ def __init__(self, config_path: str = None): self.config = self._load_config(config_path) # 初始化各模块 self.discovery = TopicDiscovery() self.generator = ContentGenerator() self.publisher = XHSPublisherAdapter() # 日志 self.log_dir = self.config.get('paths', {}).get('log_dir', './logs') os.makedirs(self.log_dir, exist_ok=True) def _load_config(self, config_path: str) -> dict: """加载配置""" if not config_path: config_path = os.path.join( os.path.dirname(__file__), '..', 'config', 'config.json' ) try: with open(config_path, 'r', encoding='utf-8') as f: return json.load(f) except Exception as e: print(f"配置加载失败: {e},使用默认配置") return { 'workflow': { 'search_keyword': 'AI科技', 'search_limit': 5, 'content_style': 'tech' } } def _log(self, message: str): """记录日志""" timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') log_message = f"[{timestamp}] {message}" print(log_message) # 写入日志文件 log_file = os.path.join( self.log_dir, f"workflow_{datetime.now().strftime('%Y%m%d')}.log" ) with open(log_file, 'a', encoding='utf-8') as f: f.write(log_message + '\n') def run(self, keyword: str = None, topic: str = None, style: str = None, dry_run: bool = False) -> bool: """ 执行完整工作流 Args: keyword: 搜索关键词(自动发现模式) topic: 直接指定话题(直接创作模式) style: 内容风格 dry_run: 仅生成不发布 Returns: 是否成功 """ self._log("🚀 工作流启动") # 模式1:自动发现热点 if keyword and not topic: self._log(f"🔍 搜索热门话题: {keyword}") notes = self.discovery.search_notes(keyword, limit=5) if not notes: self._log("❌ 未找到热门笔记") return False # 选择第一篇 selected_note = notes[0] self._log(f"✅ 选中笔记: {selected_note['title'][:40]}...") # 提取话题 topic = self.discovery.extract_topic(selected_note) self._log(f"🏷️ 提取话题: {topic}") # 模式2:直接创作 if not topic: topic = self.config.get('workflow', {}).get('search_keyword', 'AI科技') self._log(f"📝 使用默认话题: {topic}") # AI创作内容 self._log("🤖 AI创作原创内容...") style = style or self.config.get('workflow', {}).get('content_style', 'tech') content = self.generator.generate(topic, style=style) self._log(f"✅ 内容生成完成") self._log(f" 标题: {content['title']}") self._log(f" 正文长度: {len(content['body'])} 字符") # 去AI化处理 self._log("🎭 去AI化处理...") content = self.generator.humanize(content) # 保存到文件 output_file = os.path.join( self.config.get('paths', {}).get('output_dir', './output'), f"content_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" ) with open(output_file, 'w', encoding='utf-8') as f: json.dump(content, f, ensure_ascii=False, indent=2) self._log(f"💾 内容已保存: {output_file}") # 发布 if dry_run: self._log("🧪 试运行模式,跳过发布") return True self._log("📱 发布到小红书...") success = self.publisher.publish( title=content['title'], content=content['body'], tags=content['tags'], style=style ) if success: self._log("🎉 发布成功!") else: self._log("❌ 发布失败") return success def main(): """命令行入口""" parser = argparse.ArgumentParser(description='小红书热点趋势工作流') parser.add_argument('--keyword', '-k', help='搜索关键词(自动发现模式)') parser.add_argument('--topic', '-t', help='直接指定话题(直接创作模式)') parser.add_argument('--style', '-s', default='tech', choices=['tech', 'warm', 'business'], help='内容风格') parser.add_argument('--dry-run', '-d', action='store_true', help='仅生成不发布') parser.add_argument('--config', '-c', help='配置文件路径') args = parser.parse_args() # 创建工作流 workflow = XHSTrendingWorkflow(args.config) # 执行 success = workflow.run( keyword=args.keyword, topic=args.topic, style=args.style, dry_run=args.dry_run ) sys.exit(0 if success else 1) if __name__ == "__main__": main()