Skip to content

Repository files navigation

Weekly Newsletter Scraper

一个用于抓取各种技术周刊的 Python 工具集合。

功能特性

  • 🚀 智能去重: 自动检测重复内容,避免重复处理
  • 📊 并行执行: 支持多线程并行抓取,提高效率
  • 🔄 状态跟踪: 记录每次运行的状态,支持断点续传
  • 📝 内容总结: 使用 AI 自动生成中文摘要
  • 🎯 精准抓取: 支持多个主流技术周刊
  • 📣 完成通知: 每个周刊处理完全部文章链接后发送 Telegram 消息

支持的周刊

脚本名称 周刊名称 描述
frontendfoc.py Frontend Focus Frontend 开发相关周刊
javascriptweekly.py JavaScript Weekly JavaScript 开发周刊
nextjsweekly.py Next.js Weekly Next.js 框架周刊
nodeweekly.py Node Weekly Node.js 开发周刊
pythonweekly.py Python Weekly Python 开发周刊
reactweekly.py React Weekly React 开发周刊
reactdigest.py React Digest React 技术文摘
thisweekinreact.py This Week in React React 生态系统周刊
tailwindweekly.py Tailwind Weekly Tailwind CSS 与前端开发周刊
webtoolsweekly.py Web Tools Weekly Web 开发工具周刊

安装依赖

pip install requests beautifulsoup4 openai python-dotenv

环境配置

创建 .env 文件并配置以下环境变量:

# DeepSeek API 配置
DEEPSEEK_API_KEY=your_deepseek_api_key_here
DEEPSEEK_BASE_URL=https://api.deepseek.com

# Telegram 完成通知
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
TELEGRAM_CHAT_ID=your_telegram_chat_id_here

使用方法

1. 使用主入口文件 (推荐)

# 执行所有脚本
python main.py

# 显示帮助信息
python main.py --help

# 列出所有可用脚本
python main.py --list

# 只执行指定脚本
python main.py frontendfoc nodeweekly

# 设置并发数 (默认4)
python main.py --workers 8

# 使用8个并发执行所有脚本
python main.py -w 8 --all

2. 单独执行脚本

# 执行单个脚本
python frontendfoc.py
python javascriptweekly.py
# ... 其他脚本

输出文件

  • 所有生成的文件保存在 outputs/ 目录下
  • 文件格式为 Markdown (.md)
  • 文件名格式:{脚本名}_{期刊标题}_summary.md
  • 运行状态记录在 last_run_info.json 文件中

智能去重机制

系统会自动记录每次运行抓取的链接 URL,如果检测到相同的链接,会自动跳过执行:

{
  "frontendfoc": {
    "issue_title": "Issue #123",
    "link_url": "issues/123",
    "timestamp": "2025-09-11T10:30:00.123456",
    "full_url": "https://frontendfoc.us/issues/123"
  }
}

命令行选项

main.py 选项

选项 说明
-h, --help 显示帮助信息
-l, --list 列出所有可用脚本
-w, --workers N 设置最大并发数 (默认:4)
-a, --all 执行所有脚本 (默认行为)

项目结构

weekly-gen/
├── main.py                 # 兼容入口(委托到 src.main)
├── src/
│   ├── __init__.py
│   ├── main.py             # 主入口(并行执行)
│   ├── frontendfoc.py      # Frontend Focus 爬虫
│   ├── javascriptweekly.py # JavaScript Weekly 爬虫
│   ├── nextjsweekly.py     # Next.js Weekly 爬虫
│   ├── nodeweekly.py       # Node Weekly 爬虫
│   ├── reactweekly.py      # React Weekly 爬虫
│   ├── reactdigest.py      # React Digest 爬虫
│   ├── thisweekinreact.py  # This Week in React 爬虫
│   ├── tailwindweekly.py   # Tailwind Weekly 爬虫
│   ├── webtoolsweekly.py   # Web Tools Weekly 爬虫
│   └── utils/
│       ├── __init__.py
│       ├── last_run_tracker.py
│       ├── deepseek_api.py
│       ├── extract_links_and_summarize.py
│       └── proxy.py
├── app/                    # FastAPI 服务与调度器
├── outputs/                # 输出文件目录
├── last_run_info.json      # 运行状态记录
└── README.md               # 说明文档

使用示例

快速开始

  1. 安装依赖并配置环境变量
  2. 执行所有脚本:
    python main.py

高级用法

# 只抓取React相关的周刊
python main.py reactweekly reactdigest thisweekinreact

# 使用更高并发数加速执行
python main.py --workers 8

# 查看执行状态
cat last_run_info.json

注意事项

  1. 网络代理: 代理逻辑已集中在 src/utils/proxy.py。默认:
    • 容器内:http://host.docker.internal:7897
    • 容器外:http://127.0.0.1:7897 可通过环境变量覆盖:PROXY_URLPROXY_HOST/PROXY_PORT/PROXY_SCHEME,或标准 HTTP_PROXY/HTTPS_PROXY
  2. API 限制: 注意 DeepSeek API 的调用频率限制
  3. 超时设置: 单个脚本执行超时时间为 5 分钟
  4. 错误处理: 系统具有完善的错误处理和重试机制
  5. Telegram 通知: 只有找到并处理至少一个文章链接后才发送。通知失败只写入日志,不改变抓取任务的成功状态

故障排除

常见问题

  1. 导入错误: 确保所有依赖都已安装
  2. API 错误: 检查.env文件中的 API 配置
  3. 网络错误: 检查代理设置和网络连接
  4. 权限错误: 确保有写入outputs/目录的权限

日志查看

所有执行日志都会实时显示在终端,包括:

  • 执行开始时间
  • 成功/失败状态
  • 执行耗时
  • 错误详情

服务化与部署(FastAPI + uv + Docker)

  • 服务:基于 FastAPI,默认会在 Asia/Shanghai 时区下每天 09:00 在后台执行一次 python main.py -w 8 --all(避免并发重叠)。
  • 依赖管理:通过 uvpyproject.toml 同步安装。
  • 日志:运行日志保存至 outputs/service_logs/,最近一次运行日志路径会在 /status 返回。
  • 调度器状态会持久化到 outputs/service_state.json,保存最近一次执行信息和下一次计划时间。
  • 服务重启后,/status 仍然可以读取上一次执行结果。
  • 该持久化机制不会补跑停机期间错过的计划任务。
  • 调度模式:
    • SCHEDULE_MODE=daily 时,按 SCHEDULE_TZSCHEDULE_TIME 固定时刻执行
    • SCHEDULE_MODE=interval 时,按 TASK_INTERVAL_SECONDS 固定间隔执行

本地运行(uv)

# 同步依赖
uv sync

# 启动服务(默认 8111 端口),内部调度执行 src.main
uv run uvicorn app.server:app --host 0.0.0.0 --port 8111

# interval 模式:每 10 分钟执行一次
TASK_INTERVAL_SECONDS=600 uv run uvicorn app.server:app --host 0.0.0.0 --port 8111

# daily 模式:每天 09:00(Asia/Shanghai)执行一次
SCHEDULE_MODE=daily SCHEDULE_TIME=09:00 SCHEDULE_TZ=Asia/Shanghai \
uv run uvicorn app.server:app --host 0.0.0.0 --port 8111

接口:

  • GET /healthz:健康检查
  • GET /status:查看后台任务状态
  • POST /run-now:立即触发一次执行(若正在运行会返回 409)

Docker 运行

docker build -t weekly-gen:latest .
docker run --rm -p 8111:8111 \
  -e SCHEDULE_MODE=daily \
  -e SCHEDULE_TIME=09:00 \
  -e SCHEDULE_TZ=Asia/Shanghai \
  -e RUN_CMD="python -m src.main -w 8 --all" \
  -e RUNNING_IN_CONTAINER=1 \
  -v "$(pwd)/outputs:/app/outputs" \
  -v "$(pwd)/last_run_info.json:/app/last_run_info.json" \
  --name weekly-gen weekly-gen:latest

打镜像(构建与推送)

使用 Compose(支持自定义镜像名与标签):

# 构建
IMAGE_NAME=yourrepo/weekly-gen IMAGE_TAG=$(git rev-parse --short HEAD) docker compose build

# 推送(需先登录到对应 Registry)
IMAGE_NAME=yourrepo/weekly-gen IMAGE_TAG=$(git rev-parse --short HEAD) docker compose push

或使用 Makefile(简化命令):

# 构建
make build IMAGE_NAME=yourrepo/weekly-gen IMAGE_TAG=$(git rev-parse --short HEAD)

# 推送
make push IMAGE_NAME=yourrepo/weekly-gen IMAGE_TAG=$(git rev-parse --short HEAD)

docker-compose 部署

项目已提供 docker-compose.yml,默认将容器内的 /app/outputs 映射到宿主机 ./outputs。 默认调度模式为每天 09:00Asia/Shanghai)。

docker compose up -d --build

说明:项目中实际使用的目录为 outputs/(复数)。如需与文档中 output/(单数)保持一致,请调整 compose 映射或脚本中的输出目录。

代理注意事项(容器)

容器内已通过 compose 添加 extra_hosts: host.docker.internal:host-gateway,可直接使用宿主机代理。若需自定义:

  • 设置 PROXY_URL(例如:http://host.docker.internal:7897)或标准 HTTP_PROXY/HTTPS_PROXY
  • Linux 环境若不支持 host.docker.internal,请确保 Docker 版本支持 host-gateway,或手动配置网络。

贡献

欢迎提交 Issue 和 Pull Request 来改进这个项目!

许可证

MIT License

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages