这件事对开发者的真正信号
特朗普政府移除国家公园内数十块涉及美国负面历史的标识,法院命令恢复。你不需要关心党派政治,但你需要关心:当任意机构可以单方面抹除公共记录时,技术能否提供“不可篡改”的备份和“自动审计”的能力?
作为开发者,这件新闻意味着:
- 政府网页/公开信息可能在短期内容易被批量修改或删除
- 法院强制恢复的前提是有记录可查——如果没人提前保存原始内容,恢复就是空话
- 我们需要一套低成本的自动化监控+归档系统,让任何公开变更都留下证据
下面我直接给一个可运行的项目,实现:
- 定时抓取指定政府网站页面
- 对比内容变化,用AI摘要出差异
- 每次变化自动提交到Git仓库(版本历史)
- 同时上传到IPFS,生成不可更改的CID(内容标识)
- 通过一个简单的Web仪表盘展示变更时间线和IPFS链接
产品Demo效果展示
假设监控的是美国国家公园管理局(NPS)的“African American Civil War Memorial”页面。
- 当页面内容被修改/删除时,系统会在1分钟内检测到
- Git log显示“2026-06-18 删除‘disparage Americans’相关描述”
- IPFS返回永久链接:
https://ipfs.io/ipfs/QmX...,该链接指向被抓取时的原始冻结 - 仪表盘上红色标记“疑似删除”,绿色标记“新增内容”
图:监控仪表盘,左侧时间线,右侧变更详情与IPFS链接(关键词:digital change monitoring dashboard)
技术选型
| 组件 | 技术 | 理由 |
|---|---|---|
| 爬虫 | Python + httpx | 异步支持,比requests快;自动处理重定向 |
| 内容对比 | diff-match-patch + GPT-4o-mini摘要 | 精确的行级diff + 自然语言描述变化 |
| 版本控制 | Git Python库 (gitpython) | 无需额外服务,每变更自动commit |
| 不可篡改存储 | IPFS (通过ipfs-http-client) | 内容寻址,一旦上传无法修改 |
| 定时触发 | GitHub Actions | 免费,每30分钟可跑一次 |
| 可视化 | Streamlit | 快速部署,支持markdown渲染 |
为什么不用简单的网页存档?
- Internet Archive虽好,但抓取频率低(几天一次),且可被robots.txt阻止
- 自己搭建Git+IPFS完全可控,且任何人有API Key即可查询历史
核心代码实现
1. 抓取与差异检测
import hashlib
import json
from pathlib import Path
from git import Repo
import httpx
from diff_match_patch import diff_match_patch
# 要监控的URL列表
URLS = [
"https://www.nps.gov/nama/learn/historyculture/african-american-civil-war-memorial.htm",
# 可添加更多
]
def fetch_page(url: str) -> str:
headers = {"User-Agent": "GovMonitor/1.0"}
resp = httpx.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp.text
def get_hash(content: str) -> str:
return hashlib.sha256(content.encode()).hexdigest()
def diff_texts(old: str, new: str) -> str:
dmp = diff_match_patch()
diffs = dmp.diff_main(old, new)
dmp.diff_cleanupSemantic(diffs)
html = dmp.diff_prettyHtml(diffs)
return html
2. Git版本管理
REPO_PATH = "/data/monitor_repo"
def init_repo():
if not Path(REPO_PATH).exists():
return Repo.init(REPO_PATH)
return Repo(REPO_PATH)
def commit_change(repo: Repo, url: str, content: str, hash_val: str):
file_path = f"pages/{url.split('//')[1].replace('/', '_')}.html"
full_path = Path(REPO_PATH) / file_path
full_path.parent.mkdir(parents=True, exist_ok=True)
full_path.write_text(content)
repo.index.add([file_path])
repo.index.commit(f"Update {url} | hash={hash_val}")
3. IPFS上传(需要本地或远程IPFS节点)
import ipfshttpclient
def upload_to_ipfs(content: str) -> str:
client = ipfshttpclient.connect('/ip4/127.0.0.1/tcp/5001')
res = client.add_bytes(content.encode())
return res # 返回CID,如 QmX...
4. AI摘要变化(可选,用OpenAI)
from openai import OpenAI
client = OpenAI()
def summarize_change(old_text: str, new_text: str) -> str:
prompt = f"""比较以下两个版本的内容,用一句话概括主要变化。
旧版:{old_text[:1000]}
新版:{new_text[:1000]}
变化摘要:"""
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
max_tokens=60
)
return resp.choices[0].message.content.strip()
项目结构和配置
gov-monitor/
├── .github/
│ └── workflows/
│ └── monitor.yml # GitHub Actions 定时触发(每30分钟)
├── src/
│ ├── __init__.py
│ ├── scraper.py # 抓取页面
│ ├── differ.py # 对比和摘要
│ ├── git_manager.py # Git提交
│ ├── ipfs_manager.py # IPFS上传
│ ├── monitor.py # 主入口
│ └── dashboard.py # Streamlit仪表盘
├── requirements.txt
├── .env.example # 配置 API KEY 等
└── README.md
关键配置 .env
OPENAI_API_KEY=sk-...
IPFS_NODE_URL=/ip4/127.0.0.1/tcp/5001
GIT_REPO_PATH=/data/monitor_repo
GitHub Actions 定时任务 (monitor.yml)
name: Monitor Government Pages
on:
schedule:
- cron: '*/30 * * * *' # 每30分钟
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -r requirements.txt
- run: python src/monitor.py
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
上线要注意的坑
IPFS节点必须持久化 - GitHub Actions每次新环境,IPFS上传后如果不pin,内容可能丢失。解决方案:自己跑一个pinata节点或使用Pinata/Filecoin的远程pinning服务。免费pinata每月1GB够用。
速率限制 - 政府网站可能限制高频请求。建议抓取间隔至少30秒,或者加上随机延迟。可以先用
httpx.Limits控制并发。robots.txt遵守 - 虽然技术可以绕过,但如果被抓到可能惹法律麻烦。本系统只用于公共信息,且建议在
User-agent中注明用途。存储膨胀 - 每次全量存储HTML,几个月后可能数百MB。解决方案:只存储diff(增量),但Git本身存储差异,实际上全量存储也ok,每个版本算一次。若担心,压缩存储:
zlib.compress(content)。AI摘要费用 - 如果几十个页面每次变化都调API,费用会累积。建议:变化超过一定阈值(如20%字符变化)才调用AI摘要;或者仅对敏感关键词匹配(如“remove”、“delete”)触发。
开发者现在可以做什么
- 立即Fork这个项目(我把完整代码放在GitHub:
github.com/yeqingyuan/gov-monitor),改成监控你关心的任何网站(比如你所在城市的政府公示、法规条例) - 把监控结果做成公开仪表盘,用Vercel/Streamlit Community Cloud免费部署,任何人都可以查看变更历史
- 结合区块链时间戳(比如通过opentimestamps将每次commit的hash登记到比特币链上),提供更强的公证力。这不是必须的,但如果用于法律证据,推荐加上。
我的判断:在政治极化加剧的背景下,公共信息的“易逝性”会越来越严重。技术方案虽然不能阻止删除,但可以确保删除本身留下记录。Git+IPFS这套组合,成本极低(一个月不到1美元),却能让每次修改都无可抵赖。这不只是工具,而是数字时代的公民基础设施。