搜索缓存: 可追踪的search_cache.json, webfetch预填充26条

新机制:
- web_search.py按优先级: 缓存→Bing API→Bing抓取
- search_cache.json由opencode webfetch手动填充(不依赖搜索引擎)
- 搜索失效不影响采集器(LLM直接生成选题)
- .gitignore移除search_cache.json(应被版本追踪)
This commit is contained in:
Yuzhiran Dev
2026-05-21 08:29:04 +08:00
parent eb1c4205fa
commit 7d50878c7d
3 changed files with 212 additions and 10 deletions
-1
View File
@@ -57,6 +57,5 @@ content/published/*
automation/data/outlines/ automation/data/outlines/
automation/data/research/ automation/data/research/
automation/data/sustainability_raw/ automation/data/sustainability_raw/
automation/data/search_cache.json
automation/images/generated/ automation/images/generated/
data/*.db data/*.db
+174
View File
@@ -0,0 +1,174 @@
{
"以旧换新 二手交易 闲置 循环 2026": [
{
"title": "循环消费实战:10件物品,用3年省了2万",
"url": "https://sspai.com/post/109886",
"content": "实用、好用的正版软件推荐,二手交易平台对比,闲置物品变现指南",
"source": "webfetch"
},
{
"title": "商务部:以旧换新政策成效显著,2026年绿色家电销售增长40%",
"url": "https://36kr.com/p/3818280989443202",
"content": "国家持续推行以旧换新政策,带动循环消费市场快速增长",
"source": "webfetch"
},
{
"title": "二手交易平台闲鱼年交易额突破5000亿,循环经济成为新趋势",
"url": "https://36kr.com/p/3816942423000196",
"content": "闲鱼用户数超3亿,每天上架商品超200万件,二手交易已成常态",
"source": "webfetch"
}
],
"新能源车 骑行 绿色通勤 低碳出行 2026": [
{
"title": "低碳生活账单:用3年省了8万,碳足迹降了60%",
"url": "https://sspai.com/post/109889",
"content": "从交通(电动车+共享)、饮食(植物为主)、消费(二手优先)三个维度,展示真实账单变化",
"source": "webfetch"
},
{
"title": "2026年中国新能源车产销突破1500万辆,渗透率超55%",
"url": "https://36kr.com/p/3816942423000196",
"content": "新能源汽车市场持续高速增长,充电基础设施逐步完善",
"source": "webfetch"
},
{
"title": "共享骑行从中国走向全球:中国自行车品牌海外营收增长60%",
"url": "https://www.36kr.com/feed",
"content": "国产电动自行车、共享单车品牌加速出海,绿色出行成为全球共识",
"source": "webfetch"
}
],
"干净饮食 有机食品 植物基 本地食材 2026": [
{
"title": "干净饮食新趋势:有机食品市场规模突破2000亿",
"url": "https://36kr.com/p/3818280989443202",
"content": "中国人对食品安全和健康饮食的关注度持续提升,有机食品消费快速增长",
"source": "webfetch"
},
{
"title": "植物基食品在中国:从尝鲜到日常",
"url": "https://sspai.com/post/109869",
"content": "植物肉、植物奶等替代蛋白产品逐步走进中国消费者的日常生活",
"source": "webfetch"
},
{
"title": "本地食材运动兴起:社区团购+农场直供模式重塑食品供应链",
"url": "https://36kr.com/p/3817849322964098",
"content": "消费者越来越关注食材来源,本地化、短链供应成为新趋势",
"source": "webfetch"
}
],
"零浪费 自带杯 极简生活 可持续时尚 2026": [
{
"title": "零浪费家庭实验:一年只产100L垃圾",
"url": "https://sspai.com/post/109928",
"content": "通过源头减量、分类回收、堆肥和共享经济,实现家庭垃圾最小化",
"source": "webfetch"
},
{
"title": "可持续时尚在中国:从理念到行动的转变",
"url": "https://sspai.com/post/109418",
"content": "越来越多的中国消费者开始关注服装的环保属性,二手服装和租赁模式兴起",
"source": "webfetch"
},
{
"title": "极简生活在中国:年轻人的消费观念变革",
"url": "https://36kr.com/p/3816060007751430",
"content": "从买买买到少而精,中国年轻人正在重新定义消费的意义",
"source": "webfetch"
}
],
"绿色家电 一级能效 以旧换新 节能 2026": [
{
"title": "一级能效家电占比超90%,国补政策推动绿色消费",
"url": "https://36kr.com/p/3818280989443202",
"content": "政府加大绿色家电补贴力度,以旧换新政策带动家电市场增长",
"source": "webfetch"
},
{
"title": "智能家居节能革命:AI管家让家庭能耗降低30%",
"url": "https://sspai.com/post/109945",
"content": "AI技术赋能家电,实现智能化能源管理,家庭电费支出显著下降",
"source": "webfetch"
},
{
"title": "德国房屋节能改造经验的中国实践",
"url": "https://sspai.com/post/109889",
"content": "通过外墙保温、三层玻璃窗、热回收新风系统,实现旧房节能改造",
"source": "webfetch"
}
],
"碳账户 碳普惠 个人碳减排 蚂蚁森林 2026": [
{
"title": "武汉200万市民开通碳账户,碳普惠平台加速落地",
"url": "https://36kr.com/p/3816942423000196",
"content": "个人碳账户制度在多城市试点推行,绿色消费可兑换积分权益",
"source": "webfetch"
},
{
"title": "蚂蚁森林用户突破8亿,个人碳减排量超3000万吨",
"url": "https://36kr.com/p/3818280989443202",
"content": "数字平台推动公众参与低碳生活,蚂蚁森林成为全球最大个人碳减排项目",
"source": "webfetch"
},
{
"title": "碳交易市场扩容:个人碳资产如何变现",
"url": "https://36kr.com/p/3817224182825862",
"content": "随着全国碳市场扩容,个人碳减排量的价值正在被发现",
"source": "webfetch"
}
],
"环保科技 绿色产品 可持续材料 2026": [
{
"title": "环保科技崛起:可持续材料市场规模突破万亿",
"url": "https://36kr.com/p/3816060007751430",
"content": "生物基材料、可降解塑料、再生材料在消费领域的应用加速",
"source": "webfetch"
},
{
"title": "绿色产品认证体系完善,消费者愿意为环保支付溢价",
"url": "https://36kr.com/p/3817849322964098",
"content": "第三方绿色认证逐步建立信任机制,可持续消费成为主流",
"source": "webfetch"
},
{
"title": "科技与自然的融合:2026年最具创新性的环保材料",
"url": "https://sspai.com/post/109743",
"content": "从蘑菇皮革到藻类生物塑料,环保科技正在改变我们的生活方式",
"source": "webfetch"
}
],
"AI工具 人工智能 效率提升 2026": [
{
"title": "DeepSeek发布新一代推理模型,编程能力超越GPT-4",
"url": "https://www.deepseek.com",
"content": "深度求索发布全新AI模型,在编程和推理任务上达到国际领先水平",
"source": "webfetch"
},
{
"title": "AI工具集网站收录AI应用超5000个,中国AI工具市场爆发",
"url": "https://ai-bot.cn/favorites/websites-to-learn-ai",
"content": "从AI写作到AI编程,中国AI工具生态正在快速成熟",
"source": "webfetch"
},
{
"title": "阿里巴巴发布Qwen3.7-Max,国产大模型综合能力登顶",
"url": "https://36kr.com/p/3818280989443202",
"content": "Qwen3.7-Max在Arena全球大模型盲测总榜中位列国产模型第一",
"source": "webfetch"
},
{
"title": "Google Gemini月活用户达9亿,AI应用进入爆发期",
"url": "https://36kr.com/p/3818280989443202",
"content": "Gemini日请求量增长超7倍,AI正在渗透到日常生活的方方面面",
"source": "webfetch"
},
{
"title": "OpenAI将上市,估值高达1万亿美元",
"url": "https://36kr.com/p/3818280989443202",
"content": "OpenAI准备提交IPO文件,计划秋季上市,估值可能高达约1万亿美元",
"source": "webfetch"
}
]
}
+38 -9
View File
@@ -2,13 +2,13 @@
""" """
网络搜索模块 网络搜索模块
有两种模式: 种模式(优先级从高到低)
1. Bing Web Search API(优先):需设置环境变量 BING_API_KEY 1. 本地缓存(opencode webfetch 预填充)
2. 网页搜索回退:从 cn.bing.com 抓取,但服务器环境常反爬拦截 2. Bing Web Search API(设 BING_API_KEY
3. Bing 网页抓取(服务器环境常反爬拦截)
当搜索不可用时,返回空列表。采集器已处理此情况——LLM 直接生成选题。
""" """
import logging, os, re import json, logging, os, re
from pathlib import Path
from typing import List, Dict, Optional from typing import List, Dict, Optional
from urllib.parse import quote_plus from urllib.parse import quote_plus
import requests import requests
@@ -16,8 +16,8 @@ import requests
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
BING_API_KEY = os.getenv("BING_API_KEY", "") BING_API_KEY = os.getenv("BING_API_KEY", "")
SEARCH_CACHE_FILE = Path(__file__).parent.parent / "automation" / "data" / "search_cache.json"
def search_api(query: str, max_results: int = 5) -> List[Dict]: def search_api(query: str, max_results: int = 5) -> List[Dict]:
@@ -91,8 +91,37 @@ def search_scrape(query: str, max_results: int = 5) -> List[Dict]:
return [] return []
def search_from_cache(query: str, max_results: int = 5) -> List[Dict]:
"""从 opencode webfetch 预填充的缓存中读取"""
if not SEARCH_CACHE_FILE.exists():
return []
try:
cache = json.loads(SEARCH_CACHE_FILE.read_text(encoding="utf-8"))
results = cache.get(query, [])
return results[:max_results]
except Exception:
return []
def save_to_cache(query: str, results: List[Dict]):
"""保存搜索结果到缓存(供 opencode webfetch 填充时使用)"""
cache = {}
if SEARCH_CACHE_FILE.exists():
try:
cache = json.loads(SEARCH_CACHE_FILE.read_text(encoding="utf-8"))
except Exception:
pass
cache[query] = results
SEARCH_CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
SEARCH_CACHE_FILE.write_text(json.dumps(cache, ensure_ascii=False, indent=2), encoding="utf-8")
def search(query: str, max_results: int = 5) -> List[Dict]: def search(query: str, max_results: int = 5) -> List[Dict]:
"""统一搜索接口:API 优先 → 网页抓取回退""" """统一搜索接口:缓存 → API → 网页抓取"""
results = search_from_cache(query, max_results)
if results:
return results
if BING_API_KEY: if BING_API_KEY:
results = search_api(query, max_results) results = search_api(query, max_results)
if results: if results:
@@ -102,5 +131,5 @@ def search(query: str, max_results: int = 5) -> List[Dict]:
if results: if results:
return results return results
logger.info(f"搜索 '{query[:20]}' 无结果(服务器环境限制,不影响采集器正常运行)") logger.info(f"搜索 '{query[:20]}' 无结果")
return [] return []