Files
inspiration-collector/scripts/summarize_news.py

137 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Use DeepSeek to summarize top news into categorized Chinese briefs (5 per category)."""
import json, os, requests
from datetime import datetime, timezone, timedelta
API_KEY = "sk-bbca4a0380d549389f0d27cdea0b5228"
API_URL = "https://api.deepseek.com/v1/chat/completions"
MODEL = "deepseek-v4-flash"
NEWS_FILE = "/var/www/nav/data/news.json"
OUTPUT = "/var/www/nav/data/news_summary.json"
tz = timezone(timedelta(hours=8))
def load_raw_news():
if not os.path.exists(NEWS_FILE):
return []
with open(NEWS_FILE) as f:
data = json.load(f)
return data.get("items", [])
def summarize(items):
news_text = ""
for i, item in enumerate(items[:30], 1):
title = item.get("title", "")
summary = item.get("summary", "")[:150].replace("<", "").replace(">", "")
source = item.get("source", "")
news_text += f"{i}. [{source}] {title}\n {summary}\n\n"
prompt = f"""你是一个新闻整理助手。以下是来自BBC世界新闻、BBC中文、新浪新闻、涌报、Hacker News的最新资讯。
请从以上内容中精选出最重要的新闻按以下分类组织每个分类最多5条
分类要求:
- 国际要闻:全球政治、外交、军事
- 科技前沿AI、软件、硬件、互联网
- 财经动向:市场、经济、商业
- 中国热点:中国相关新闻
- 社会生活:健康、环境、文化、民生
每条新闻格式:
## 小标题10字以内概括核心
正文200-300字中文精炼摘要包含核心事实和背景
输出格式为JSON
{{
"categories": [
{{
"name": "国际要闻",
"items": [
{{"rank": 1, "subtitle": "小标题", "title": "原标题", "source": "BBC World", "summary": "正文..."}},
...
]
}},
...
]
}}
注意:
- 每个分类最多5条
- 小标题要精炼抓人
- 摘要要有信息量,不要空话
- 只输出JSON不要其他内容
原始新闻:
{news_text}"""
resp = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={
"model": MODEL,
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.4,
"max_tokens": 8000,
},
timeout=180,
)
if resp.status_code != 200:
print(f"API error: {resp.status_code} {resp.text[:200]}")
return None
content = resp.json()["choices"][0]["message"]["content"]
content = content.strip()
if content.startswith("```"):
lines = content.split("\n")
content = "\n".join(lines[1:-1]) if lines[-1].strip() == "```" else "\n".join(lines[1:])
try:
result = json.loads(content)
except:
# Try to fix common JSON issues
content = content.strip()
# Remove trailing commas before closing brackets
import re
content = re.sub(r',\s*}', '}', content)
content = re.sub(r',\s*]', ']', content)
try:
result = json.loads(content)
except:
print(f"JSON parse failed, len={len(content)}")
print(f"First 800 chars: {content[:800]}")
return None
return result
if __name__ == "__main__":
now = datetime.now(tz).strftime("%Y-%m-%d %H:%M")
items = load_raw_news()
if not items:
print("No news data")
exit(0)
print(f"Loaded {len(items)} raw news items. AI summarizing by category...")
data = summarize(items)
if not data:
print("Summarization failed")
exit(1)
result = {
"updated_at": now,
"categories": data.get("categories", []),
}
total = sum(len(c["items"]) for c in result["categories"])
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
with open(OUTPUT, "w", encoding="utf-8") as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f"Written {total} articles across {len(result['categories'])} categories")
for c in result["categories"]:
print(f" {c['name']}: {len(c['items'])} items")