
Hot Topics Selector
- 25 installs
- 5 repo stars
- Updated April 7, 2026
- cyhzzz/finance_aigc_skills
Scrapes financial news headlines and filters them into quality topics that can be linked to investment and account-opening content.
About
This skill fetches financial hot-news headlines and intelligently filters them into topics suited to guiding investment and fund content. A financial content creator uses it to pick topics that lead toward brokerage or fund conversions.
- Phased pipeline: scrape 133 headlines, filter to 5 topics, then parse full plans
- Python handles scraping while the agent handles selection and parsing
Hot Topics Selector by the numbers
- 25 all-time installs (skills.sh)
- Ranked #1,459 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cyhzzz/finance_aigc_skills --skill hot_topics_selectorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 25 |
|---|---|
| repo stars | ★ 5 |
| Last updated | April 7, 2026 |
| Repository | cyhzzz/finance_aigc_skills ↗ |
What it does
Scrapes financial news headlines and filters them into quality topics that can be linked to investment and account-opening content.
Files
财经热点选题工具
本 Skill 用于从财经热点中筛选出适合引导投资理财的优质选题。
核心工作流
Phase 0: 数据抓取(Python)
→ 获取133个新闻标题
Phase 1: Agent 智能筛选(Markdown 提示词)
→ 筛选出5个选题
Phase 2: 内容抓取(Python)
→ 抓取5篇新闻详细内容
Phase 3: Agent 智能解析(Markdown 提示词)
→ 生成5个完整选题方案职责分离:
- Python 脚本:数据抓取(Phase 0, 2)
- Agent:智能筛选和解析(Phase 1, 3)
---
Phase 0: 数据抓取
执行方式:
cd scripts
python3 fetch_hot_topics.py输出:/tmp/hot_topics.json
包含内容:
- 133个新闻标题(5个平台)
- 微博、百度、今日头条、抖音、财联社
数据格式:
{
"fetch_time": "2026-02-13T19:36:24+08:00",
"total_items": 133,
"data": {
"weibo": { "items": [...], "count": 30 },
"baidu": { "items": [...], "count": 30 }
}
}---
Phase 1: Agent 智能筛选
Agent 执行提示词:
你是一个财经内容选题专家。请根据以下新闻标题,筛选出5个最适合引导证券开户/基金投资的选题。
标题列表
{从 /tmp/hot_topics.json 读取的133个标题}
筛选标准(投资关联性为核心)
最高优先级(90-100分)
可直接关联投资产品:
- 赚钱故事 → AI基金/科技股票/券商产品
- 投资案例 → 黄金ETF/资产配置
- 理财话题 → 基金定投/证券开户
示例:
- "AI月入200万" → 可推荐AI基金(95分)
- "黄金赚196万" → 可推荐黄金ETF(92分)
高优先级(80-89分)
可关联理财规划:
- 薪资话题 → 工资收入vs投资收入
- 储蓄话题 → 存钱vs投资
- 消费话题 → 理财规划
示例:
- "年终奖1.8亿" → 可推荐基金定投(85分)
中优先级(60-79分)
勉强可关联:
- 教育话题 → 教育基金
- 养老话题 → 养老金投资
示例:
- "衡水中学变了" → 可关联教育基金(70分)
不选择(<60分)
无法关联投资:
- 纯娱乐八卦
- 纯社会新闻
- 与财经无关的话题
输出格式(JSON)
{
"selected_indices": [1, 3, 5, 7, 9],
"reasons": {
"1": "✅ 可直接关联:AI赚钱 → AI基金投资。投资关联度95分,大众关注度高",
"3": "✅ 可直接关联:黄金案例 → 黄金ETF。投资关联度92分,数据冲击强"
},
"investment_angles": {
"1": "可以推荐:AI主题基金、科技股票、券商AI产品",
"3": "可以推荐:黄金ETF、券商黄金产品、资产配置服务"
},
"investment_relevance_score": {
"1": 95,
"3": 92
}
}严格要求: 1. 固定选择5个标题(不多不少) 2. 每个标题投资关联度 ≥80分 3. 说明具体的投资产品推荐方向 4. 优先选择可直接关联产品的选题(≥90分)
---
Phase 2: 内容抓取
执行方式:
cd scripts
python3 fetch_news_content.py \
--input /tmp/hot_topics.json \
--indices 1,3,5,7,9 \
--output /tmp/news_content.json输入:Phase 1 输出的5个选题索引
输出:/tmp/news_content.json
包含内容:
- 5篇新闻的完整内容
- 标题、URL、平台、正文、关键词
数据格式:
{
"fetch_time": "2026-02-13T21:00:00+08:00",
"total_articles": 5,
"articles": [
{
"index": 1,
"title": "杭州大哥开1人公司靠AI月入200万",
"url": "https://...",
"platform": "微博",
"content": "完整新闻内容...",
"keywords": ["AI", "创业", "月入200万"]
}
]
}---
Phase 3: Agent 智能解析
Agent 执行提示词:
你是一个财经内容策划专家。请根据以下5篇新闻内容,为每篇新闻生成完整的选题方案。
新闻列表
{从 /tmp/news_content.json 读取的5篇新闻}
解析要求
1. 新闻内容概要
- 提取核心信息(100-150字)
- 保留关键数据和案例
- 突出与投资相关的信息
2. 选题理由
- 说明投资关联度(80-100分)
- 分析大众关注度
- 预测传播潜力
3. 引导策略
- 切入点:如何从新闻话题切入
- 转折点:如何自然转向投资
- 产品推荐:具体推荐哪些投资产品
- 话术示例:2-3句引导话术
示例引导策略:
切入点:AI创业月入200万,引发"我也能吗"的思考
转折点:普通人不会技术,但可以通过投资分享红利
产品推荐:AI主题基金、科技ETF、券商AI产品
话术示例:
"想参与AI红利?不需要会技术,投资AI基金就能分一杯羹"
"开户买AI基金,普通人也能享受AI发展的红利"4. 原始链接
- 保留完整的新闻URL
- 方便后续查阅和引用
输出格式(JSON)
{
"topic_plans": [
{
"index": 1,
"title": "杭州大哥开1人公司靠AI月入200万",
"summary": "杭州一创业者通过AI工具运营1人公司,月收入达200万。主要业务是...",
"selection_reason": {
"investment_relevance": 95,
"mass_attention": "高(AI+赚钱话题)",
"viral_potential": "极强(月入200万数据冲击)"
},
"guidance_strategy": {
"entry_point": "AI创业月入200万,引发'我也能吗'的思考",
"turning_point": "普通人不会技术,但可以通过投资分享AI红利",
"product_recommendation": "AI主题基金、科技ETF、券商AI产品",
"script_examples": [
"想参与AI红利?投资AI基金就能分一杯羹",
"开户买AI基金,普通人也能享受AI发展红利"
]
},
"source_url": "https://..."
}
]
}严格要求: 1. 每个选题都要有完整的4个部分 2. 引导策略要具体、可操作 3. 产品推荐要与券商/基金相关 4. 话术要自然、不生硬
---
使用示例
完整流程
# Step 1: 数据抓取
python3 scripts/fetch_hot_topics.py
# Step 2: Agent 智能筛选
# Agent 读取本文件 Phase 1 提示词并执行
# Step 3: 内容抓取
python3 scripts/fetch_news_content.py \
--input /tmp/hot_topics.json \
--indices 1,3,5,7,9
# Step 4: Agent 智能解析
# Agent 读取本文件 Phase 3 提示词并执行总耗时:约15分钟
---
脚本说明
scripts/fetch_hot_topics.py
功能:调用 TrendRadar API,抓取5个平台的热点新闻标题
输出:133个新闻标题(JSON)
scripts/fetch_news_content.py
功能:根据选题索引,抓取新闻详细内容
输入:选题索引(如 1,3,5,7,9)
输出:5篇新闻完整内容(JSON)
---
参考资料
references/选题方法论.md
包含财经新媒体大V的选题方法论,包括:
- 5大核心方法论(痛点驱动、情绪共鸣、数据冲击、故事表达、实用导向)
- 选题公式(数字+冲突+结果、痛点+解决方案等)
- 评估标准(传播性40%、相关性30%、实用性20%、合规性10%)
Agent 可根据需要参考此文件优化选题策略。
---
注意事项
- 投资关联性为核心:每个选题都必须可以自然转向证券开户或基金投资
- 固定输出5个选题:不多不少,确保质量
- 投资关联度 ≥80分:低于80分的选题会被排除
- Python 负责数据:Agent 不需要执行数据抓取
- Agent 负责智能:筛选和解析由 Agent 完成
财经新媒体大V选题方法论
📚 参考来源
典型财经大V:
- 半佛仙人(硬核财经)
- 巫师财经(深度分析)
- 财经早餐(资讯快读)
- 刘润(商业洞察)
- 小Lin说(通俗易懂)
🎯 选题核心方法论
1. 痛点驱动
从生活痛点切入,而非专业概念
❌ 错误:"如何理解通货膨胀" ✅ 正确:"为什么你的钱越来越不值钱了?"
原理:
- 大众不关心专业概念
- 只关心对自己的影响
- 痛点是最强的吸引力
2. 情绪共鸣
引发情绪,而非单纯传递信息
❌ 错误:"黄金价格上涨20%" ✅ 正确:"5年前买黄金,现在赚196万!你错过了吗?"
情绪类型:
- 焦虑:房价、养老、就业
- 希望:赚钱、副业、投资
- 好奇:富豪生活、内幕揭秘
- 愤怒:不公平、被割韭菜
3. 数据冲击
用数据说话,增加可信度
❌ 错误:"黄金是很好的投资" ✅ 正确:"2700克金条卖出,赚196万!年化收益18%!"
数据要素:
- 具体数字(不要"很多",要"196万")
- 对比数据(5年前 vs 现在)
- 可视化(图表、对比)
4. 故事化表达
用故事讲道理,而非说教
❌ 错误:"定投的重要性" ✅ 正确:"打工30年攒300万,靠的不是工资,而是..."
故事要素:
- 主角(普通人更好)
- 冲突(困难、挑战)
- 转折(发现、改变)
- 结果(成功、收获)
5. 实用导向
给出可操作建议,而非泛泛而谈
❌ 错误:"投资要分散风险" ✅ 正确:"普通人如何投资黄金?这3种方式最靠谱"
实用要素:
- 具体步骤(第一步、第二步、第三步)
- 避坑指南(不要做什么)
- 工具推荐(用什么)
🎨 选题公式
公式1:数字+冲突+结果
模板: [具体数字] + [冲突/对比] + [结果]
案例:
- "月入200万的AI生意,普通人能做吗?"
- "5年前买黄金,现在赚196万!"
- "公司利润2.7亿,年终奖1.8亿!你的呢?"
公式2:痛点+解决方案
模板: [痛点] + [如何解决]
案例:
- "工资不够花?这个副业让你月入过万"
- "存钱30年不如投资3年?"
- "年终奖发了,怎么理财才能不贬值?"
公式3:故事+启示
模板: [故事] + [启示/教训]
案例:
- "返乡大哥打工30年攒300万,秘诀竟然是..."
- "我朋友炒股亏了50万,原因是..."
- "这个月入200万的AI生意,背后的真相是..."
公式4:对比+结论
模板: [A vs B] + [结论]
案例:
- "存钱 vs 投资,哪个更划算?"
- "买房 vs 买黄金,现在该选哪个?"
- "年终奖 vs 投资收益,哪个更靠谱?"
🎯 选题角度
角度1:从生活切入
不直接讲投资,从生活话题切入
案例:
- 生活话题:年终奖
- 转向投资:年终奖怎么理财?
- 最终引导:资产配置、开户咨询
转化路径:
看到年终奖标题(吸引)
→ 想到自己的年终奖(共鸣)
→ 看到理财建议(教育)
→ 想要开户投资(转化)角度2:从案例切入
用真实案例,增加可信度
案例:
- 案例:5年前买黄金赚196万
- 转向投资:普通人如何投资黄金?
- 最终引导:黄金投资工具、开户
角度3:从焦虑切入
利用焦虑情绪,提供解决方案
案例:
- 焦虑:钱越来越不值钱
- 转向投资:通胀对冲工具
- 最终引导:资产配置建议
角度4:从趋势切入
抓住热点趋势,顺势而为
案例:
- 趋势:AI大火
- 转向投资:普通人如何投资AI?
- 最终引导:AI主题基金、开户
📊 选题评估标准
1. 传播性(40%)
评估维度:
- 是否有情绪共鸣?
- 是否有数据冲击?
- 是否有故事性?
- 标题是否吸引人?
2. 相关性(30%)
评估维度:
- 与大众生活相关吗?
- 能自然转向投资吗?
- 目标受众明确吗?
3. 实用性(20%)
评估维度:
- 能给出具体建议吗?
- 有可操作性吗?
- 有避坑指南吗?
4. 合规性(10%)
评估维度:
- 不触碰敏感话题?
- 不传播虚假信息?
- 可以加入风险提示?
🎯 实战应用
案例分析:AI月入200万
原始标题: "杭州大哥开1人公司靠AI月入200万"
优化版本:
版本1(痛点+解决方案): "不会AI也能月入200万?普通人如何分一杯羹?"
版本2(故事+启示): "月入200万的AI生意,背后的真相是..."
版本3(数据冲击): "1人公司+AI=月入200万!这个公式你也能复制吗?"
版本4(对比+结论): "打工 vs AI创业,哪个更赚钱?月入200万案例告诉你答案"
推荐版本: 版本2或3
- 有故事性(杭州大哥)
- 有数据冲击(200万)
- 引发好奇(背后的真相)
- 可以转向投资(普通人如何分享AI红利)
🚀 集成到选题工具
Phase 1 优化:大模型筛选提示词
新增筛选标准:
- 是否符合"痛点驱动"?
- 是否有情绪共鸣?
- 是否有数据或故事?
- 是否有实用价值?
Phase 3 优化:选题方案生成
自动生成:
- 5个标题版本(应用不同公式)
- 创作角度(生活/案例/焦虑/趋势)
- 转化路径(如何引导到投资)
- 风险提示(合规要求)
---
核心总结:
财经大V的选题方法论 = 痛点驱动 + 情绪共鸣 + 数据冲击 + 故事表达 + 实用导向
最终目标: 从"不炒股的普通人" → "有投资兴趣的潜在客户"
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
财经热点抓取工具
基于 TrendRadar 项目能力,抓取真实热点资讯
"""
import json
import time
import random
import argparse
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Tuple, Optional, Union
import requests
import pytz
class HotTopicsFetcher:
"""热点抓取器"""
# API 基础地址
API_BASE_URL = "https://newsnow.busiyi.world/api/s"
# 支持的平台
PLATFORMS = {
"cls-hot": "财联社热门",
"_36kr": "36氪",
"gelonghui": "格隆汇",
"toutiao": "今日头条",
"baidu": "百度热搜",
"weibo": "微博",
"douyin": "抖音",
"zhihu": "知乎",
}
# 财经相关平台(专业)
FINANCE_PLATFORMS = ["cls-hot", "_36kr", "gelonghui"]
# 综合资讯平台(大众关注度高)
GENERAL_PLATFORMS = ["toutiao", "baidu", "weibo", "douyin", "zhihu"]
# 默认推荐平台(平衡专业和大众)
RECOMMENDED_PLATFORMS = ["weibo", "baidu", "toutiao", "cls-hot", "douyin"]
def __init__(self, proxy_url: Optional[str] = None):
self.proxy_url = proxy_url
self.session = requests.Session()
def fetch_platform_data(
self,
platform_id: str,
max_retries: int = 2,
retry_wait: int = 3
) -> Tuple[Optional[Dict], str]:
"""
抓取指定平台的热点数据
Args:
platform_id: 平台ID(如 cls-hot)
max_retries: 最大重试次数
retry_wait: 重试等待时间(秒)
Returns:
(数据字典, 平台名称)
"""
platform_name = self.PLATFORMS.get(platform_id, platform_id)
url = f"{self.API_BASE_URL}?id={platform_id}&latest"
# 配置代理
proxies = None
if self.proxy_url:
proxies = {"http": self.proxy_url, "https": self.proxy_url}
# 请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
}
# 重试逻辑
for attempt in range(max_retries + 1):
try:
response = self.session.get(url, proxies=proxies, headers=headers, timeout=10)
response.raise_for_status()
data = json.loads(response.text)
return data, platform_name
except Exception as e:
if attempt < max_retries:
wait_time = retry_wait + random.uniform(1, 2) * attempt
print(f"⚠️ {platform_name} 抓取失败: {e},{wait_time:.1f}秒后重试...")
time.sleep(wait_time)
else:
print(f"❌ {platform_name} 抓取失败: {e}")
return None, platform_name
return None, platform_name
def fetch_all_platforms(
self,
platforms: Optional[List[str]] = None,
request_interval: int = 1000
) -> Dict:
"""
抓取多个平台的热点数据
Args:
platforms: 平台列表,None 表示使用财经平台
request_interval: 请求间隔(毫秒)
Returns:
包含所有平台数据的字典
"""
if platforms is None:
platforms = self.FINANCE_PLATFORMS
results = {}
print(f"\n🔍 开始抓取 {len(platforms)} 个平台的热点...")
print(f"平台列表: {', '.join([self.PLATFORMS.get(p, p) for p in platforms])}")
for i, platform_id in enumerate(platforms):
data, platform_name = self.fetch_platform_data(platform_id)
if data and "items" in data:
results[platform_id] = {
"name": platform_name,
"items": data["items"],
"count": len(data["items"])
}
print(f"✅ {platform_name}: {len(data['items'])} 条")
else:
results[platform_id] = {
"name": platform_name,
"items": [],
"count": 0
}
print(f"❌ {platform_name}: 0 条")
# 请求间隔
if i < len(platforms) - 1:
interval = request_interval / 1000 + random.uniform(-0.1, 0.1)
time.sleep(max(0.5, interval))
return results
def filter_by_keywords(
self,
data: Dict,
include_keywords: Optional[List[str]] = None,
exclude_keywords: Optional[List[str]] = None
) -> Dict:
"""
根据关键词过滤热点
Args:
data: 原始数据
include_keywords: 包含关键词列表
exclude_keywords: 排除关键词列表
Returns:
过滤后的数据
"""
if not include_keywords and not exclude_keywords:
return data
filtered_data = {}
for platform_id, platform_data in data.items():
filtered_items = []
for item in platform_data.get("items", []):
title = item.get("title", "")
# 检查排除关键词
if exclude_keywords:
if any(kw.lower() in title.lower() for kw in exclude_keywords):
continue
# 检查包含关键词
if include_keywords:
if not any(kw.lower() in title.lower() for kw in include_keywords):
continue
filtered_items.append(item)
filtered_data[platform_id] = {
**platform_data,
"items": filtered_items,
"count": len(filtered_items)
}
return filtered_data
def save_to_file(
self,
data: Dict,
output_path: Optional[str] = None,
filename_prefix: str = "hot_topics"
) -> str:
"""
保存数据到 JSON 文件
Args:
data: 热点数据
output_path: 输出路径
filename_prefix: 文件名前缀
Returns:
保存的文件路径
"""
if output_path is None:
output_path = "/tmp"
Path(output_path).mkdir(parents=True, exist_ok=True)
# 生成文件名
timestamp = datetime.now(pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d_%H%M%S")
filename = f"{filename_prefix}_{timestamp}.json"
filepath = Path(output_path) / filename
# 添加元数据
output_data = {
"fetch_time": datetime.now(pytz.timezone("Asia/Shanghai")).isoformat(),
"platforms_count": len(data),
"total_items": sum(p.get("count", 0) for p in data.values()),
"data": data
}
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(output_data, f, ensure_ascii=False, indent=2)
print(f"\n💾 数据已保存: {filepath}")
return str(filepath)
def print_summary(self, data: Dict):
"""打印数据摘要"""
print("\n" + "="*60)
print("📊 热点数据摘要")
print("="*60)
total_items = sum(p.get("count", 0) for p in data.values())
print(f"总平台数: {len(data)}")
print(f"总热点数: {total_items}")
print("\n各平台数据:")
for platform_id, platform_data in data.items():
name = platform_data.get("name", platform_id)
count = platform_data.get("count", 0)
print(f" • {name}: {count} 条")
# 显示 Top 5
print("\n🔥 综合热度 Top 5:")
all_items = []
for platform_id, platform_data in data.items():
for idx, item in enumerate(platform_data.get("items", [])[:10], 1):
all_items.append({
"title": item.get("title", ""),
"rank": idx,
"platform": platform_data.get("name", ""),
"url": item.get("url", ""),
})
# 按排名排序
all_items.sort(key=lambda x: x["rank"])
for i, item in enumerate(all_items[:5], 1):
print(f"{i}. {item['title']}")
print(f" 来源: {item['platform']} | 排名: #{item['rank']}")
print("="*60)
def main():
"""主函数"""
parser = argparse.ArgumentParser(description='财经热点抓取工具')
parser.add_argument('--platforms', type=str, help='平台列表(逗号分隔)')
parser.add_argument('--keywords', type=str, help='包含关键词(逗号分隔)')
parser.add_argument('--exclude', type=str, help='排除关键词(逗号分隔)')
parser.add_argument('--output', type=str, default='/tmp', help='输出路径')
parser.add_argument('--finance', action='store_true', help='只抓取财经平台')
args = parser.parse_args()
# 初始化抓取器
fetcher = HotTopicsFetcher()
# 确定平台列表
if args.platforms:
platforms = [p.strip() for p in args.platforms.split(',')]
elif args.finance:
platforms = HotTopicsFetcher.FINANCE_PLATFORMS
else:
# 默认使用推荐平台(平衡专业和大众)
platforms = HotTopicsFetcher.RECOMMENDED_PLATFORMS
# 抓取数据
data = fetcher.fetch_all_platforms(platforms)
# 关键词过滤
include_keywords = [k.strip() for k in args.keywords.split(',')] if args.keywords else None
exclude_keywords = [k.strip() for k in args.exclude.split(',')] if args.exclude else None
if include_keywords or exclude_keywords:
print("\n🔍 应用关键词过滤...")
data = fetcher.filter_by_keywords(data, include_keywords, exclude_keywords)
# 保存数据
filepath = fetcher.save_to_file(data, args.output)
# 打印摘要
fetcher.print_summary(data)
return filepath
if __name__ == "__main__":
main()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
抓取新闻详细内容
根据选题索引,从原始数据中提取URL并抓取详细内容
"""
import json
import argparse
import requests
from pathlib import Path
from datetime import datetime
import pytz
import time
from typing import List, Dict
import re
class NewsContentFetcher:
"""新闻内容抓取器"""
def __init__(self, input_file: str, indices: List[int]):
self.input_file = input_file
self.indices = indices
self.data = self._load_data()
def _load_data(self) -> Dict:
"""加载原始数据"""
with open(self.input_file, 'r', encoding='utf-8') as f:
return json.load(f)
def _extract_urls_by_indices(self) -> List[Dict]:
"""根据索引提取URL"""
all_items = []
for platform_id, platform_data in self.data.get("data", {}).items():
for rank, item in enumerate(platform_data.get("items", []), 1):
all_items.append({
"platform": platform_data.get("name", platform_id),
"rank": rank,
"title": item.get("title", ""),
"url": item.get("url", ""),
})
# 根据索引提取
selected_items = []
for idx in self.indices:
if 1 <= idx <= len(all_items):
selected_items.append(all_items[idx - 1])
return selected_items
def _fetch_content(self, url: str) -> str:
"""抓取新闻内容"""
if not url:
return "无链接"
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers, timeout=10)
response.encoding = 'utf-8'
# 简单的内容提取(实际项目中可能需要更复杂的解析)
# 这里只是示例,实际需要根据具体网站进行解析
text = response.text
# 移除HTML标签
text = re.sub(r'<[^>]+>', '', text)
# 移除多余空白
text = re.sub(r'\s+', ' ', text)
# 截取前2000字
content = text[:2000]
return content
except Exception as e:
return f"抓取失败: {str(e)}"
def fetch_all_content(self) -> Dict:
"""抓取所有选中新闻的内容"""
selected_items = self._extract_urls_by_indices()
articles = []
for idx, item in enumerate(selected_items, 1):
print(f"正在抓取第 {idx}/{len(selected_items)} 篇: {item['title']}")
# 抓取内容
content = self._fetch_content(item['url'])
# 提取关键词(简单示例)
keywords = self._extract_keywords(item['title'])
article = {
"index": self.indices[idx - 1],
"title": item['title'],
"url": item['url'],
"platform": item['platform'],
"content": content,
"publish_time": datetime.now(pytz.timezone("Asia/Shanghai")).isoformat(),
"keywords": keywords
}
articles.append(article)
# 避免请求过快
time.sleep(1)
result = {
"fetch_time": datetime.now(pytz.timezone("Asia/Shanghai")).isoformat(),
"total_articles": len(articles),
"articles": articles
}
return result
def _extract_keywords(self, title: str) -> List[str]:
"""提取关键词(简单示例)"""
keywords = []
keyword_list = ["AI", "黄金", "基金", "股票", "投资", "理财", "赚钱", "创业"]
for keyword in keyword_list:
if keyword in title:
keywords.append(keyword)
return keywords
def save(self, output_path: str):
"""保存结果"""
result = self.fetch_all_content()
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f"\n✓ 内容已保存: {output_path}")
print(f"总计: {result['total_articles']} 篇文章")
return result
def main():
"""主函数"""
parser = argparse.ArgumentParser(description='抓取新闻详细内容')
parser.add_argument('--input', type=str, required=True, help='输入文件路径(JSON)')
parser.add_argument('--indices', type=str, required=True, help='选题索引,逗号分隔(如:1,3,5,7,9)')
parser.add_argument('--output', type=str, default='/tmp/news_content.json', help='输出文件路径')
args = parser.parse_args()
# 解析索引
indices = [int(x.strip()) for x in args.indices.split(',')]
# 初始化抓取器
fetcher = NewsContentFetcher(args.input, indices)
# 抓取并保存
fetcher.save(args.output)
if __name__ == "__main__":
main()