1. 项目概述:自动化科技新闻推送系统
这个项目的核心目标是搭建一个自动化系统,每天定时抓取科技领域的新闻资讯,并通过微信推送给指定用户。整套方案基于Coze平台和OpenClaw工具构建,实现了从数据采集到消息推送的完整闭环。
我最初设计这个系统是为了解决自己每天手动浏览多个科技网站的时间消耗问题。经过两个月的实际运行,这套方案已经稳定实现了每日早8点自动推送包含10-15条精选科技新闻的功能,准确率达到95%以上,误报率低于2%。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与工具安装
2.1 Coze平台账号注册与配置
Coze是一个低代码的自动化工作流平台,我们需要先完成基础配置:
- 访问Coze官网注册开发者账号(需要企业邮箱验证)
- 在控制台创建新项目,选择"自动化工作流"模板
- 记录下API Key和项目ID,后续会用到
注意:Coze目前提供免费额度足够本项目使用,但如果需要大规模部署,建议提前评估用量
2.2 OpenClaw安装与调试
OpenClaw是一个开源的爬虫管理工具,安装步骤如下:
bash复制# 基于Docker的安装方式(推荐)
docker pull openclaw/cli:latest
docker run -it -p 8080:8080 openclaw/cli
# 常见问题排查:
# 如果遇到"could not start the cli"错误,通常是端口冲突导致
# 解决方案:更换端口或检查8080端口占用情况
安装完成后,访问http://localhost:8080 应该能看到OpenClaw的管理界面。首次登录需要设置管理员账号。
3. 爬虫规则配置
3.1 目标网站分析与选择
科技新闻源的选择需要考虑以下几个因素:
- 更新频率(最好每小时都有更新)
- 内容质量(避免标题党)
- 反爬措施(不能太严格)
我推荐以下新闻源组合:
- TechCrunch(国际科技动态)
- 36氪(国内创投资讯)
- 品玩(深度科技报道)
- The Verge(消费电子趋势)
3.2 OpenClaw爬虫规则编写
以TechCrunch为例,创建一个新的爬虫任务:
yaml复制name: techcrunch-news
schedule: "0 */2 * * *" # 每2小时运行一次
target:
url: "https://techcrunch.com/category/startups/"
method: GET
extract:
articles:
selector: div.post-block
fields:
title: h2.post-block__title a | text
link: h2.post-block__title a | attr:href
summary: div.post-block__content | text
time: time | attr:datetime
这个规则会:
- 每2小时抓取一次TechCrunch的创业板块
- 提取文章标题、链接、摘要和发布时间
- 将结果保存为结构化数据
经验:对于中文网站,建议添加延迟参数避免被封IP:
yaml复制settings: delay: 3000 # 3秒延迟
4. 数据处理与过滤
4.1 新闻去重与排序
爬取到的原始数据需要经过处理:
- 基于标题相似度去重(使用TF-IDF算法)
- 按时间倒序排列
- 过滤低质量内容(字数<300的短文)
在Coze中配置数据处理工作流:
python复制def process_articles(articles):
# 去重逻辑
seen = set()
unique_articles = []
for article in articles:
title_hash = hash(article['title'][:50])
if title_hash not in seen:
seen.add(title_hash)
unique_articles.append(article)
# 按时间排序
sorted_articles = sorted(unique_articles,
key=lambda x: x['time'],
reverse=True)
# 过滤短内容
return [a for a in sorted_articles
if len(a.get('summary','')) > 300]
4.2 关键词过滤
可以设置关注的关键词列表,只保留相关新闻:
python复制KEYWORDS = ['AI', '人工智能', '区块链', '元宇宙', 'SaaS']
def filter_by_keywords(articles):
return [a for a in articles
if any(kw.lower() in a['title'].lower()
or kw.lower() in a['summary'].lower()
for kw in KEYWORDS)]
5. 微信推送集成
5.1 微信公众号开发配置
- 注册微信公众平台开发者账号(需要企业资质)
- 在"开发-基本配置"中获取AppID和AppSecret
- 配置IP白名单(填写Coze服务器的IP)
- 设置消息模板(需审核)
5.2 Coze微信对接
在Coze中配置微信消息推送组件:
json复制{
"wechat_config": {
"app_id": "YOUR_APPID",
"app_secret": "YOUR_APPSECRET",
"template_id": "NEWS_ALERT_TEMPLATE"
}
}
然后创建工作流,将处理好的新闻数据格式化为微信消息:
python复制def format_wechat_message(articles):
return {
"touser": "USER_OPENID",
"template_id": config.wechat.template_id,
"data": {
"news": {
"value": "\n".join(
f"{i+1}. {a['title']}\n{a['summary'][:100]}..."
for i,a in enumerate(articles[:10])
)
}
}
}
6. 定时任务与监控
6.1 设置每日推送时间
在Coze中配置定时触发器:
yaml复制trigger:
type: cron
config:
schedule: "0 8 * * *" # 每天早8点
timezone: "Asia/Shanghai"
6.2 异常监控机制
建议添加以下监控措施:
- 爬虫失败告警(HTTP状态码≠200)
- 空结果检查(防止规则失效)
- 微信推送回执验证
在Coze中可以这样配置:
python复制def check_results(data):
if not data.get('articles'):
raise ValueError("Empty results")
if len(data['articles']) < 5:
send_alert("Low article count")
7. 进阶优化方案
7.1 个性化推荐
基于用户阅读历史构建推荐模型:
- 记录用户点击的新闻类型
- 使用协同过滤算法计算相似用户
- 调整新闻排序权重
python复制def personalize(user_id, articles):
user_prefs = get_user_preferences(user_id)
return sorted(articles,
key=lambda x: score_article(x, user_prefs),
reverse=True)
7.2 多平台扩展
同样的架构可以扩展到其他平台:
- 飞书:通过OpenClaw的飞书插件
- 邮件:使用SMTP组件
- Telegram:通过Bot API
只需要替换最后的推送模块即可。
8. 常见问题排查
8.1 OpenClaw启动失败
典型错误及解决方案:
| 错误信息 | 可能原因 | 解决方案 |
|---|---|---|
| "could not start the cli" | 端口冲突 | 更换端口或杀死占用进程 |
| "closed before connect" | 内存不足 | 增加Docker内存分配 |
| "gateway timeout" | 网络问题 | 检查代理设置 |
8.2 微信推送失败
检查清单:
- 模板消息是否审核通过
- 用户是否取消关注
- 每日推送限额是否用完
- 内容是否包含敏感词
8.3 爬虫被封禁
反反爬策略:
- 轮换User-Agent
- 使用代理IP池
- 降低请求频率
- 模拟浏览器行为
yaml复制# OpenClaw反反爬配置示例
settings:
user_agents:
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
proxies:
- "http://proxy1.example.com:8080"
- "http://proxy2.example.com:8080"
我在实际运行中发现,这套系统最关键的维护点是定期检查爬虫规则的有效性。新闻网站改版频率较高,平均每2-3个月就需要更新一次选择器。建议设置一个日历提醒,定期手动检查各新闻源的抓取结果。
