#!/usr/bin/env python3 """ 小红书内容转换器 - 修复版 专门处理IT资讯自动化系统生成的Markdown文件 """ import re import logging from typing import Dict, List, Optional, Tuple from dataclasses import dataclass logger = logging.getLogger(__name__) @dataclass class Article: """文章数据结构""" title: str content: str source: str = "" url: str = "" keywords: List[str] = None def __post_init__(self): if self.keywords is None: self.keywords = [] @dataclass class XiaohongshuContent: """小红书内容结构""" title: str content: str cover_suggestions: List[str] = None tags: List[str] = None def __post_init__(self): if self.cover_suggestions is None: self.cover_suggestions = [] if self.tags is None: self.tags = [] class ContentConverterFixed: """修复版内容转换器""" def __init__(self, config: Optional[Dict] = None): self.config = config or {} logger.info("修复版内容转换器初始化完成") def parse_markdown(self, markdown_content: str) -> Article: """ 解析Markdown文件,提取真正的文章内容 Args: markdown_content: Markdown文件内容 Returns: 文章对象 """ lines = markdown_content.split('\n') # 提取标题(第一行) title = "" if lines and lines[0].startswith('# '): title = lines[0][2:].strip() # 查找文章内容部分 content_start = -1 for i, line in enumerate(lines): if line.strip() == "## 📰 文章内容(DeepSeek翻译)": content_start = i + 1 break # 提取真正的文章内容 - 修复:只提取DeepSeek翻译的正文 content_lines = [] if content_start > 0: # 跳过空行和可能的标题标记行 i = content_start while i < len(lines): line = lines[i].strip() # 跳过空行和标题标记行 if not line or line.startswith('**标题:') or line.startswith('**核心内容翻译:'): i += 1 continue # 找到真正的内容开始 break # 收集真正的文章内容(直到下一个##标题或---分隔符) while i < len(lines): line = lines[i] # 如果遇到下一个标题或分隔符,停止收集 if line.startswith('## ') or line.strip() == '---': break content_lines.append(line) i += 1 # 如果还是没有找到,尝试查找中文内容 if not content_lines: for i, line in enumerate(lines): # 查找典型的中文内容开始 if '本文报道了' in line or '文章指出' in line or '主要观点' in line: # 从这个段落开始收集 j = i while j < len(lines) and not lines[j].startswith('## ') and lines[j].strip() != '---': if lines[j].strip(): content_lines.append(lines[j]) j += 1 break # 如果还是没有,使用整个内容 if not content_lines: content_lines = lines content = '\n'.join(content_lines).strip() # 提取来源 source = "" for line in lines: if "**来源**:" in line or "来源:" in line: match = re.search(r'[::]\s*(.+)', line) if match: source = match.group(1).strip() break # 提取原文链接 url = "" for line in lines: if "原文链接:" in line or "**原文链接**:" in line: match = re.search(r'https?://[^\s]+', line) if match: url = match.group(0).strip() break return Article( title=title, content=content, source=source, url=url ) def extract_main_content(self, content: str) -> str: """ 从文章内容中提取核心部分 Args: content: 原始文章内容 Returns: 提取后的核心内容 """ # 移除标题行 lines = content.split('\n') filtered_lines = [] for line in lines: # 跳过空行和标题行 if not line.strip(): continue if line.startswith('**标题:'): continue if line.startswith('**核心内容翻译:'): continue if line.startswith('---'): continue filtered_lines.append(line) return '\n\n'.join(filtered_lines) def to_xiaohongshu_basic(self, article: Article) -> str: """ 基础转换:将文章转换为小红书格式 Args: article: 文章对象 Returns: 小红书格式的内容 """ # 提取核心内容 main_content = self.extract_main_content(article.content) # 处理标题 title = self._process_title(article.title) # 构建小红书内容 xhs_content = "" # 开头 xhs_content += f"姐妹们!今天分享一个超实用的技术资讯\n\n" xhs_content += f"往下看 ⬇️\n\n" # 标题 xhs_content += f"【{title}】\n\n" # 来源 if article.source: xhs_content += f"来源: {article.source}\n\n" xhs_content += "—————\n\n" # 核心内容(限制长度) if main_content: # 限制内容长度(小红书适合短内容) if len(main_content) > 800: # 取前800字符,并在完整句子处截断 truncated = main_content[:800] last_period = max( truncated.rfind('。'), truncated.rfind('!'), truncated.rfind('?'), truncated.rfind('.') ) if last_period > 600: # 确保有足够内容 main_content = truncated[:last_period + 1] else: main_content = truncated + "..." xhs_content += f"{main_content}\n\n" # 结尾 xhs_content += "—————\n\n" xhs_content += "有用的话记得收藏 📌\n\n" # 标签 tags = self._generate_tags(article) xhs_content += f"{tags}\n\n" # 互动提示 xhs_content += "💬 你对这个话题有什么看法?欢迎在评论区讨论!\n" xhs_content += "⭐ 如果觉得有用,记得点赞收藏哦~\n\n" # 原文链接 if article.url: xhs_content += f"🔗 原文链接: {article.url}" return xhs_content def _process_title(self, title: str) -> str: """处理标题""" # 缩短过长的标题 if len(title) > 40: title = title[:37] + "..." return title def _generate_tags(self, article: Article) -> str: """生成标签""" base_tags = ["#来源", "#干货分享", "#实用技巧", "#技术资讯", "#科技新闻", "#技术"] # 根据来源添加特定标签 if "MIT" in article.source or "Technology Review" in article.source: base_tags.append("#MIT") base_tags.append("#AI技术") if "The Verge" in article.source: base_tags.append("#TheVerge") base_tags.append("#科技媒体") if "InfoQ" in article.source: base_tags.append("#InfoQ") base_tags.append("#开发者") return " ".join(base_tags) def convert_markdown_to_xiaohongshu(self, markdown_content: str) -> str: """ 主转换函数:将Markdown文件转换为小红书格式 Args: markdown_content: Markdown文件内容 Returns: 小红书格式的内容 """ try: # 1. 解析Markdown文件 article = self.parse_markdown(markdown_content) logger.info(f"解析文章: {article.title}") logger.info(f"来源: {article.source}") logger.info(f"内容长度: {len(article.content)} 字符") # 2. 转换为小红书格式 xhs_content = self.to_xiaohongshu_basic(article) logger.info(f"转换完成,标题: {article.title[:30]}...") return xhs_content except Exception as e: logger.error(f"转换失败: {e}") # 回退:简单转换 lines = markdown_content.split('\n') title = lines[0][2:].strip() if lines and lines[0].startswith('# ') else "技术资讯" return f"""姐妹们!今天分享一个技术资讯 往下看 ⬇️ 【{title[:30]}...】 来源: IT资讯 ————— 💡 内容处理中遇到问题,请查看原文链接获取完整内容。 ————— 有用的话记得收藏 📌 #技术资讯 #科技新闻 #干货分享 💬 你对这个话题有什么看法?欢迎在评论区讨论! ⭐ 如果觉得有用,记得点赞收藏哦~""" def test_conversion(): """测试转换功能""" converter = ContentConverterFixed() # 测试内容 test_md = """# Where OpenAI's technology could show up in Iran ## 📋 文章信息 - **来源**: MIT Technology Review - **原文标题**: Where OpenAI's technology could show up in Iran - **原文链接**: https://www.technologyreview.com/2026/03/16/1134315/where-openais-technology-could-show-up-in-iran/ - **发布日期**: None - **原文字数**: 1,227 - **文章类型**: 技术类 - **处理方式**: DeepSeek翻译 - **处理时间**: 2026-03-17 16:01:00 - **抓取时间**: 2026-03-17T16:00:27.836284 --- ## 📰 文章内容(DeepSeek翻译) **标题:OpenAI技术可能在伊朗战场出现的三个关键领域** **核心内容翻译:** 从战争边缘到战斗核心,值得关注的三个领域。 OpenAI与五角大楼达成允许其在涉密环境中使用AI技术的争议性协议已逾两周。该协议的具体授权范围仍存紧迫疑问:萨姆·奥尔特曼虽宣称军方不得用其技术开发生化武器,但协议仅要求军方遵循自身()相关准则。OpenAI另一主要声明——协议将禁止其技术用于国内监控——同样显得可疑。 OpenAI的动机尚不明确。这并非科技巨头首次违背"永不涉足"的誓言承接军事合同,但其立场转变速度之快值得注意。或许出于资金压力:OpenAI正投入巨资进行AI训练并寻求更多收入来源(包括广告)。亦或奥尔特曼真心信奉其常提及的意识形态框架:自由民主国家(及其军队)必须掌握最强AI以与中国竞争。 更关键的问题在于后续发展。随着美国升级对伊朗打击(AI在其中发挥空前作用),OpenAI已决定深入复杂的战斗核心。那么其技术具体可能出现在哪些作战环节?哪些应用会获得客户(及员工)容忍? **目标定位与打击** 尽管协议已生效,OpenAI技术何时能适配涉密环境仍不确定,因其需与军方现有工具整合(埃隆·马斯克的xAI近期也与五角大楼达成协议,其AI模型Grok预计将经历相同流程)。但整合压力迫在眉睫:在Anthropic拒绝允许其AI用于"任何合法用途"后,特朗普总统下令军方停用该技术,五角大楼更将Anthropic列为供应链风险。 **作战平台部署** 五角大楼去年秋季推出的生成式AI平台GenAI.mil,允许军事单位接入商业AI模型并执行与商业领域类似的任务。谷歌Gemini是首批入驻模型。今年1月五角大楼宣布将纳入xAI的Grok(尽管该模型曾传播反犹内容并生成非自愿深度伪造视频)。OpenAI于2月跟进,宣布其模型将用于起草政策文件、合同及协助任务行政支持。 虽然使用该平台处理非密任务的人员对伊朗敏感决策影响有限,但OpenAI入驻具有更深层意义:这呼应了赫格塞斯在五角大楼全力推行的AI全覆盖战略(即便许多早期用户并不完全明确使用场景)。其传递的信号是:AI正在重塑美国作战的每个环节——从目标判定到文书工作,而OpenAI正日益赢得其中份额。 --- 处理信息: DeepSeek API | 耗时: 14.24秒 --- 原文链接: https://www.technologyreview.com/2026/03/16/1134315/where-openais-technology-could-show-up-in-iran/ 处理时间: 2026-03-17 16:01:00 ## 🖼️ 文章图片 1. ![Sam Altman collage](../images/open-ai-dow.jpg) *描述: Sam Altman collage* """ result = converter.convert_markdown_to_xiaohongshu(test_md) print("=" * 60) print("修复版转换器测试结果") print("=" * 60) print(result) print("=" * 60) print(f"内容长度: {len(result)} 字符") if __name__ == "__main__": logging.basicConfig(level=logging.INFO) test_conversion()