从 CCTV 主页抓取《新闻联播》,下载 → 转 MP3/WAV → 静音切分 → ASR 识别 → LLM 校对 → 切分为单条新闻 → 入库 MySQL。 主要内容: - 全链路:getVideo5 抓取下载、audioRead 转写、deepseek 校对与切分、newsProcess 入库 - 可移植化:配置分层,.env 只放密钥、config.yml 放模型/接入点/路由/参数 - 可换供应商:endpoints(kind/base_url/api_key_env/extra_body)+ routes 按环节选路 - 数据保真:数值事实守卫,校对改动数字/年份/届次则整片回退 ASR 原文; 识别不完整不发布该日精编,避免半天内容被当成完整一天 - 定时任务:systemd 每天 21:00,失败 21:30 / 22:00 重试; 只缺切分时只重跑切分(省掉全部 ASR),用 state/.asr_complete_* 标记判定阶段 - 隧道自愈:13306 不通时自动执行 autossh.sh(所有入口共用,systemd 托管时只等待) - 中间产物每日清理;97 项离线自检(配置/清理/事实守卫/解析/隧道)
123 lines
4.1 KiB
Python
123 lines
4.1 KiB
Python
"""
|
|
newsRedo — 手动重新执行新闻 AI 分割流程。
|
|
|
|
用法:
|
|
python newsRedo.py # 默认当天日期
|
|
python newsRedo.py 20250601 # yyyymmdd 格式
|
|
python newsRedo.py 2025-06-01 # yyyy-mm-dd 格式
|
|
python newsRedo.py 2025-06-01 --force # 已有精编记录也重新切分
|
|
|
|
流程:
|
|
1. 检查 xwlb_daily_ext 是否已有记录 → 已处理过则跳过(--force 可强制重跑)
|
|
2. 检查 xwlb_daily 是否有当天记录 → 无记录则先跑 getVideo5 全流程
|
|
3. 有记录但未处理 → 直接执行 news_to_db() AI 分割
|
|
"""
|
|
import sys
|
|
import re
|
|
import logging
|
|
from datetime import datetime
|
|
from mysqlHandle import MySQLDB
|
|
from newsProcess import news_to_db
|
|
from getVideo5 import process_videos
|
|
import config
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _parse_date(date_str):
|
|
"""解析日期,返回 (yyyymmdd_str, yyyy_mm_dd_str),或报错退出"""
|
|
if not date_str:
|
|
today = datetime.now()
|
|
d8 = today.strftime('%Y%m%d')
|
|
d10 = today.strftime('%Y-%m-%d')
|
|
logger.info(f"未指定日期,使用当天: {d10}")
|
|
return d8, d10
|
|
|
|
if re.match(r'^\d{4}-\d{2}-\d{2}$', date_str):
|
|
try:
|
|
datetime.strptime(date_str, '%Y-%m-%d')
|
|
except ValueError:
|
|
print(f"无效日期: {date_str}")
|
|
sys.exit(1)
|
|
return date_str.replace('-', ''), date_str
|
|
|
|
if re.match(r'^\d{8}$', date_str):
|
|
try:
|
|
datetime.strptime(date_str, '%Y%m%d')
|
|
except ValueError:
|
|
print(f"无效日期: {date_str}")
|
|
sys.exit(1)
|
|
return date_str, f"{date_str[:4]}-{date_str[4:6]}-{date_str[6:8]}"
|
|
|
|
print("日期格式错误,请使用 yyyymmdd 或 yyyy-mm-dd 格式")
|
|
sys.exit(1)
|
|
|
|
|
|
def main():
|
|
args = [a for a in sys.argv[1:] if not a.startswith('-')]
|
|
force = '--force' in sys.argv[1:] or '-f' in sys.argv[1:]
|
|
date_str = args[0] if args else None
|
|
date_d8, date_d10 = _parse_date(date_str)
|
|
|
|
db = MySQLDB()
|
|
|
|
# 1. 检查 xwlb_daily_ext 是否已处理过
|
|
# 判据由「>5 条」改为「存在任意记录」(原判据会把只切出 ≤5 条的日期永久判为未处理,B13)
|
|
try:
|
|
ext_count = db.query_data(
|
|
table="xwlb_daily_ext",
|
|
columns="COUNT(*) as count",
|
|
where="news_date = %s",
|
|
params=(date_d10,)
|
|
)
|
|
existing = ext_count[0]['count'] if ext_count else 0
|
|
if existing > 0 and not force:
|
|
logger.info(f"日期 {date_d10} 已有 {existing} 条精编记录,无需重新处理(需重跑请加 --force)。")
|
|
return
|
|
if existing > 0 and force:
|
|
logger.info(f"日期 {date_d10} 已有 {existing} 条精编记录,--force 将重新切分并覆盖。")
|
|
except Exception as e:
|
|
logger.error(f"查询 xwlb_daily_ext 失败: {e}")
|
|
finally:
|
|
db.close()
|
|
|
|
db = MySQLDB()
|
|
|
|
# 2. 检查 xwlb_daily 是否有当天数据
|
|
try:
|
|
daily_count = db.query_data(
|
|
table="xwlb_daily",
|
|
columns="COUNT(*) as count",
|
|
where="news_days = %s",
|
|
params=(date_d10,)
|
|
)
|
|
has_daily = daily_count and daily_count[0]['count'] > 0
|
|
except Exception as e:
|
|
logger.error(f"查询 xwlb_daily 失败: {e}")
|
|
has_daily = False
|
|
finally:
|
|
db.close()
|
|
|
|
# 3. 分支处理
|
|
if has_daily:
|
|
logger.info(f"日期 {date_d10} 在 xwlb_daily 中有记录,直接执行 AI 分割。")
|
|
try:
|
|
status = news_to_db(date_d10, force=force)
|
|
logger.info(f"news_to_db 结果: {status}")
|
|
except Exception as e:
|
|
logger.error(f"news_to_db 执行出错: {e}")
|
|
sys.exit(1)
|
|
else:
|
|
logger.info(f"日期 {date_d10} 在 xwlb_daily 中无记录,重新执行视频下载全流程。")
|
|
try:
|
|
process_videos(date_d8, date_d8)
|
|
except Exception as e:
|
|
logger.error(f"process_videos 执行出错: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
config.log_summary()
|
|
main()
|