新闻工作台

将新闻下载、文章打包、浏览器导入、排版与换号联动整合到本地控制台。

当前版本:0.2.1。下载 → 入队 → 导入 → 排版 → 人工发表 → 网站审核提示 → 受理记账 → 回首页 → 下一篇或换号。 暂时只以网站提示“新主题需要审核,您的帖子通过审核后才能显示”判定发表成功,状态仍记为已受理、审核中。原详情页标题、作者、版块与图文核对代码已注释保留,当前不执行。

启动

双击本目录的 start.command,或在本目录运行:

uv run --no-project --python 3.12 --with-requirements requirements.txt python app.py

默认打开 http://127.0.0.1:8770/ 。保留启动窗口,按 Ctrl+C 停止本地服务。修改端口使用 --port 8772;不自动打开浏览器使用 --no-browser。首次运行 uv 可能下载 Python 或依赖,后续可以复用缓存。

页面必须通过本地服务打开,不要直接双击 static/index.html。Python 依赖仅用于下载和内容处理;浏览器脚本没有远程脚本依赖。

浏览器安装与配对

  1. 在油猴安装控制台“浏览器连接”区域的两个脚本:
    • browser/local-bridge.user.js:本地连接、配对与常驻终止按钮。
    • browser/auto-news.user.js:导入、排版和任务执行。它由 importer.js、formatter.js、results.js、runner.js 构建。
  2. 停用旧的独立导入与排版油猴脚本,避免同一编辑器重复挂载。
  3. 换号插件仍由用户安装,位于项目根目录的 dww11-account-switch-browser-extension/,没有复制到本目录。本次在其 content.js 中增加了不含凭据的状态属性及终止事件监听。请在浏览器扩展管理页重新加载这个原安装目录,再刷新网站。旧 ZIP 未重新打包,不包含本次修改。
  4. 在控制台点击“显示本次连接码”。在论坛左下角“新闻工作台 · 本地连接”展开设置,填写端口和连接码并保存。
  5. 服务重启后连接码会改变,需要重新配对;任务和计数保留,但服务不会自动恢复运行。

本机 HTTP 通信通过油猴特权请求完成,不要求论坛跨域开放本地服务。真实浏览器的脚本管理器配置、本地网络权限和网站编辑器兼容性仍需首次实机验证。配对码保存在油猴存储,不写入页面全局变量。下载 API Key 不进入文章包,不发给论坛。

操作流程

  1. 填写 Key,获取频道、选择数量并下载。完整保存的文章会自动校验并进入队列;下载失败和入队失败分别显示,已保存的文章不因入队失败而删除。
  2. 也可展开“导入已有文章目录”,填写单篇目录或含多个文章子目录的根目录,点击检查。留空表示扫描本工具的 downloads/。扫描只处理根目录的一层文章子目录;文件须已完整落盘。
  3. 填写目标版块 fid、每账号最少/最多篇数和处理间隔。先核对历史发帖记录,再勾选确认并保存。版块和篇数不会替用户选择。
  4. 登录论坛,建议只保留一个执行标签。点击控制台“开始 / 继续”。执行器识别账号后领取一篇任务,进入指定新帖页、导入、排版,停止在人工审核阶段。
  5. 在论坛检查账号、版块、标题、图片位置、正文和来源,并亲手点击“发表帖子”。程序不调用发帖提交函数,不发送发帖请求,也不自动保存草稿。
  6. 人工点击时保存最终提交快照。观察网站提示“新主题需要审核,您的帖子通过审核后才能显示”即登记受理一次;暂不要求详情页标题、作者、版块、主题 ID 或图文匹配,不猜测帖子 ID。
  7. 先持久记账与去重,再回首页;在设定间隔后处理下一篇。达到账号目标且仍有待处理文章时调用换号插件,确认新 UID 和插件空闲后创建下一批次。队列为空直接结束;暂停或终止后仅记账,不自动继续。
  8. 等待超过 45 秒仍未观察到审核提示则暂停,不重复发表。仅有详情页“审核中”标志不再触发自动记账;旧的待核对任务需人工处理,不能凭此次规则改动推定成功。
  9. 已有现场结果可在暂停后使用队列中的“补核已受理结果”导入观察 JSON,并人工确认文章关联。支持本项目 local-records/publish-result-*.json 结构,字段含 title、uid、fid、threadId、postId、url、status;补核须与已有人工提交快照匹配,不增加当前批次计数。历史补核不会自动检查发布后的图文完整性。

终止、恢复与冲突

  • 队列支持勾选单篇或全选可移除文章,然后点击“移除所选文章”。请先暂停流程;移除只删除队列记录,原始文章、图片、已受理去重记录和计数保留。当前任务或提交结果未核对的文章须先核对并处理;未受理文章移除后可通过扫描目录重新入队。
  • 网站左下角悬浮窗提供“跳过本文章”:将当前未提交文章标记为“已跳过”,保留队列记录、不计发表篇数,并打开新的发帖页继续导入排版下一篇。导入中会先取消并等待回滚;已上传附件可能仍保留在网站。最后一篇跳过后流程结束。已点击发表或结果不明的文章不能直接跳过,须先人工核对。已跳过文章不会自动重新入队,需要重试时可在暂停后通过队列“人工核对 / 处理”重新排队。
  • 网站左下角常驻“终止流程”,点击后立即取消本标签可取消的导入,并通知其他安装脚本的标签和换号插件;持久状态禁止继续领取任务。
  • 控制台“终止流程”还会停止下载,浏览器在下一次连接检查时停止(正常轮询约 2 秒)。网络断开时无法承诺固定延迟;网站按钮可立即停止本标签。已到达网站的图片、登录或发帖请求无法撤回。
  • 暂停/终止后必须明确点击“开始 / 继续”。下载停止等待当前网络请求/单篇保存结束,不伪装成已经撤回在途请求。
  • 非空编辑器、人工修改、账号变化、缺图、未知来源或上传失败会停在“需要处理”,不弹自动确认覆盖旧稿。
  • 导入中刷新后不会重新上传。先核对网站附件和草稿,再决定如何处理。若需要换标签,先在控制台暂停,再在目标标签点击“接管已暂停任务”。接管不会自动重新导入内容。
  • 只有人工确认网站未受理且已清理编辑器/草稿后,才能通过队列“人工核对 / 处理”重新排队或移出。审核中、已受理和结果不明不应重试。
  • 换号插件暂停后需要通过插件现有“继续未完成流程”恢复,不重复抽号。若账号未发生变化,调度器不会猜测换号成功。

文件与数据

app.py / store.py / articles.py   本地接口、任务队列、文章校验
modules/downloader/              下载器副本与成功保存回调
modules/package.py               文章包生成器副本
browser/                         页面执行器、排版和连接脚本
static/                          操作前端
start.command                    启动入口
build_browser.py                 重建合并油猴脚本
test/                           离线测试、模拟素材、历史测试截图
data/queue.sqlite3               运行任务、计数、受理去重记录(本地)
downloads/                      本工具下载结果(本地)
  • test/history/ 保存从本目录移入的两张演示截图与演示任务 JSON。根目录其他测试文件未搬动。
  • 发布去重记录.json 是实际受理证据,继续留在原处,并在服务启动时迁入去重库。它不代表完整历史已对账。原文件可找到时还建立内容指纹;原文件丢失时仍保留原 Markdown 摘要。
  • 原始下载文件不改写。标题按 UTF-8 字节数计长:ASCII 为 1,中文和中文标点为 3,emoji 通常为 4。超过 75 时保留不超过 75 的完整前缀,再加 ...,总长最多 78;原题仍保留。
  • 排版仅处理与文章来源一致的末尾标准尾注,保留正文中的其他“来源”文字。图片顺序、标识改变会回滚排版。
  • WebP/AVIF/SVG 当前明确拦截,需用户另存支持格式并更新 Markdown;没有静默丢图或自动转码。单图须小于 20 MiB,图片 base64 总大小不超过 48 MiB。
  • 本地库含文章内容快照和账号标识,不含账号密码、Cookie 或上传凭据。运行数据和历史截图已加入忽略规则。

验证

不连接新闻 API 或真实论坛:

uv run --no-project --python 3.12 --with-requirements requirements.txt python -m unittest discover -s test -p 'test_*.py' -v
node --test test/importer.test.cjs test/bridge.test.cjs test/runner.test.cjs
# 另需 Playwright 与 Chrome,网络请求全部阻断
node --test test/results-browser.test.cjs
python3 build_browser.py

浏览器回归需要 Playwright 和本机 Chrome,使用临时独立浏览器,不使用用户配置或账号:

# 终端一:临时模拟数据服务,端口 8771
uv run --no-project --python 3.12 --with-requirements requirements.txt python test/serve_fixture.py
# 终端二:Node 环境需能加载 playwright;CHROME_PATH 可指定浏览器可执行文件
node test/browser.test.cjs

浏览器回归拦截所有真实论坛请求,仅使用模拟 HTML。截图输出到 test/artifacts/。本轮离线通过不代表已在用户登录态的真实网站上完成上传、换号或发布。

结果页资料与下一步

2026-10-31 已观察一次真实提交:网站先提示“新主题需要审核,您的帖子通过审核后才能显示”,随后进入帖子详情页,标题旁显示“审核中”。标题、作者 UID 链接、体育休闲版块 fid=90、首帖容器及审核标记已采集。详细过程见操作规范第 12 节。

注意:该地址中的数字串为 23699911,页面链接实际使用 tid=236999,首帖 PID 为 238791。适配时必须区分访问地址与主题标识,不能直接把路径中的全部数字当作 tid。

本次已完成审核中结果适配,并只读核对现有帖子的作者、版块和延迟加载图片结构。仍需公开成功页、更多明确失败提示及其他版块样本,未知结果保守暂停;当前明确拒绝分支只支持标题超限提示。不要提供 Cookie、密码或表单令牌。

0.1.1 图片修复

更新 browser/auto-news.user.js:修复实际编辑器 aid 属性识别、多行链接内图片漏导入,并增加正文图片加载与顺序检查。上传返回附件编号不再视为图片可显示;网站图片接口失败时明确停止。连接脚本及后端不需要为本次修复更新。现场发现的图片接口 HTTP 500 仍需进一步定位,不能由本次解析/校验修复宣称已解决。

0.1.2 跳过文章

保持现有控制器、SQLite 队列、连接桥和执行器的结构,新增 skip 浏览器接口及 skipped 队列状态。更新油猴中的 browser/local-bridge.user.js(0.1.1)和 browser/auto-news.user.js(0.1.2),重启本地工作台、重新配对并刷新论坛后使用。按钮位于网站左下角悬浮窗、“终止流程”上方。

0.2.0 结果核对与接续

更新油猴中的 browser/auto-news.user.js 至 0.2.0,连接脚本沿用现有 0.1.1。更新本地代码后重启服务、重新配对并刷新论坛;不会自动继续任务。新增真实 TID 与 PID 分离、链接别名防重、被动结果恢复、图文差异暂停、历史结果补核,以及记账后回首页的持久步骤。旧受理记录如只有路径数字会保留原值并标记主题身份待核对,不猜测删除 URL 后缀。

换号过程中插件暂停、超过 120 秒未确认、或执行后超过 10 秒插件空闲但 UID 未变化,流程会暂停;请在插件内核对并恢复,不自动重复抽号。图片 HTTP 500 的服务端根因仍未解决。

0.2.1 临时审核提示规则

更新油猴中的 browser/auto-news.user.js 至 0.2.1,并重启本地服务、重新配对后刷新论坛页面。连接脚本无需更新。结果适配器和执行器中的旧详情页核对代码以行注释保留;后端旧核对接口继续保留供人工历史补核使用。自动受理使用当前任务的人工提交批次校验,审核提示可不含帖子链接,不创建虚构帖子 ID。

标题自动截断

自动队列、手动目录和文章包导入均应用上述规则;已截断的标题不会重复添加省略号。已有队列在领取未开始的任务时更新标题,已导入、待审核或已提交任务保持现场标题。

应用更新:重启本地服务,并在油猴重新安装 browser/auto-news.user.js。原始 Markdown 不改写。

S
Description
No description provided
Readme
537 KiB
0 Stars 2 Watchers 0 Forks
Languages
JavaScript 65.9%
Python 30.8%
HTML 3.2%