- domestic_crawl_8g.sh: Xvfb 启动脱离管道 fd(</dev/null + 重定向日志 + disown)。 修复 2026-09-06 事故:Xvfb 常驻进程继承 'bash crawl | tee' 管道写端, tee 永远收不到 EOF → domestic_full.sh 卡死 M1 → 日报永不生成 - scheduler/reporter.py: _load_events_window 对 'publish_time 过期' 的文件 增加 mtime 兜底(本次窗口内新翻译的事件不被低质量 publish_time 误伤)。 修复空日报:date-only/美式日期错位的 publish_time 使窗口 articles=0 - configs/system.yaml: M4 翻译 provider 切换 deepseek → dashscope(qwen3.7-flash), 降低翻译成本(输出单价约降 ~9 倍);daily_report 保持 deepseek 不变
88 lines
3.0 KiB
Bash
Executable File
88 lines
3.0 KiB
Bash
Executable File
#!/bin/bash
|
||
# =============================================
|
||
# 国内服务器:8G headful + HTTP 代理抓取
|
||
# =============================================
|
||
# 适用场景:
|
||
# - 所有新闻源直接使用 headful Playwright 浏览器抓取
|
||
# - HTTP 代理 (127.0.0.1:3128) → Privoxy → SOCKS5(ss-local) 访问海外
|
||
# - 比海外 RSS 方式抓取更可靠,解决反爬问题
|
||
#
|
||
# 前置条件:
|
||
# sudo apt install xvfb
|
||
# Xvfb :99 -screen 0 1280x1024x24 </dev/null >> logs/xvfb.log 2>&1 & # 首次启动
|
||
# HTTP 代理 127.0.0.1:3128 已运行(privoxy)
|
||
#
|
||
# 用法:
|
||
# bash scripts/domestic_crawl_8g.sh # 抓取全部源
|
||
# bash scripts/domestic_crawl_8g.sh reuters # 只抓取指定源
|
||
# =============================================
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||
cd "$PROJECT_DIR"
|
||
|
||
LOG() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||
|
||
LOG "══════ 国内 8G headful + HTTP 代理抓取 ══════"
|
||
LOG "Profile: 8g_headful"
|
||
LOG "内存上限: 7500 MB"
|
||
LOG "浏览器模式: headful (Xvfb :99)"
|
||
LOG "HTTP 代理: 127.0.0.1:3128 (Privoxy → SOCKS5)"
|
||
|
||
# ── 加载 .env ──
|
||
export HTTP_PROXY=http://127.0.0.1:3128
|
||
export HTTPS_PROXY=http://127.0.0.1:3128
|
||
if [ -f .env ]; then
|
||
set -a
|
||
. ./.env
|
||
set +a
|
||
fi
|
||
|
||
# ── 启动 Xvfb(如果尚未运行)──
|
||
# ⚠️ Xvfb 的 stdin/stdout/stderr 必须脱离本脚本的 fd 并重定向到日志文件:
|
||
# 本脚本常被 `bash xx.sh | tee` 管道包裹调用(domestic_full.sh),而 Xvfb
|
||
# 是常驻进程(设计为跨运行复用)。若它继承了管道写端,抓取脚本退出后
|
||
# tee 仍永远收不到 EOF → domestic_full.sh 卡在 M1 → [2/2] 管道与日报
|
||
# 永不执行(2026-09-06 早报缺失事故根因)。
|
||
if ! pgrep -x "Xvfb" > /dev/null; then
|
||
LOG "启动 Xvfb 虚拟显示器 :99 ..."
|
||
mkdir -p logs
|
||
Xvfb :99 -screen 0 1280x1024x24 -ac +extension RANDR </dev/null >> logs/xvfb.log 2>&1 &
|
||
disown 2>/dev/null || true
|
||
sleep 1
|
||
LOG "Xvfb 已启动 (PID: $(pgrep -x Xvfb))"
|
||
else
|
||
LOG "Xvfb 已在运行 (PID: $(pgrep -x Xvfb))"
|
||
fi
|
||
|
||
export DISPLAY=:99
|
||
|
||
# ── 设置 Profile ──
|
||
export EN_NEWS_PROFILE="8g_headful"
|
||
|
||
# ── 执行抓取 ──
|
||
SOURCE_ARG=""
|
||
if [ $# -ge 1 ]; then
|
||
SOURCE_ARG="--source $1"
|
||
LOG "目标源: $1"
|
||
else
|
||
LOG "目标源: 全部启用源"
|
||
fi
|
||
|
||
if PYTHONPATH=. .venv/bin/python3 -c "
|
||
from crawler.orchestrator import run_crawl_sync
|
||
import sys
|
||
source_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||
stats = run_crawl_sync(source_filter=source_filter)
|
||
print(f'抓取完成: {stats.sources_crawled} 源, {stats.total_articles} 篇')
|
||
if stats.sources_crawled > 0 and stats.sources_failed >= stats.sources_crawled:
|
||
print(f'❌ 所有源抓取失败(sources_failed={stats.sources_failed})', file=sys.stderr)
|
||
sys.exit(1)
|
||
" "${1:-}"; then
|
||
LOG "══════ 8G 抓取完成 ✅ ══════"
|
||
else
|
||
LOG "❌ 8G 抓取失败:本次未标记完成"
|
||
exit 1
|
||
fi
|