# 3Fun SEO 根因研究交付说明

研究快照：2026-10-12。主要交付为两个 Markdown 报告、8 张图表、离线交互阅读版、加工数据、证据台账和可复现脚本。

## 阅读入口

- [根因研究报告](3fun_seo_root_cause_report.md)：原始数据审计、五假设比较、时间线、历史竞争、独立网页版本与反例。
- [可复制策略](3fun_replicable_seo_strategy.md)：产品/商业意图门槛、具体内容与内链动作、实验设计、30/60/90 天计划。
- [离线交互阅读版](index.html)：完整报告与策略、证据类型筛选、8 张图表切换、20 页样本搜索/分组/排序。浏览器直接打开即可；不需要联网脚本或服务器。
- [图表总览](chart_contact_sheet.png)：8 张 PNG 的缩略总览；charts/ 同时保存 SVG 与 2400 像素宽 PNG。
- [证据台账](data/evidence_ledger.csv)、[假设矩阵](data/hypothesis_matrix.csv)、[校验结果](data/validation.json)。

本次交付是本地研究结果，没有覆盖旧线上仪表盘，也没有自动发布到飞书或 Cloudflare。

## 数据与证据口径

1. Pages 为两期第三方预估月自然访问。保留真实缺失，仅导出集合差额分解将缺失贡献记作零；没有填造 8、9 月页面流量。
2. 排名保留历史月、行 Timestamp、源文件和 CSV 行号。Organic、AI Overview 等分开。Previous position 的比较参数未知，不构造逐月首次突破时间。
3. 两期 Pages 用完整原始 URL 精确连接；正文链接和外链目标匹配采用各自规范化规则。7 月法律 URL 的 www 归一化会产生碰撞，因此不能混用规则。
4. 当前抓取仅覆盖导出提供的候选，不等于全站。正文、文章相关模板与导航分开；去重来源/目标并排除自链接后，当前图为 914 条边。
5. 独立档案的抓取日是最迟存在日，当前页自报修改日期不是独立修改日志。词数、H2/H3、图片标签、FAQ、链接数不作为 Google 官方因果评分。
6. 历史竞争研究存在明确缺口：未恢复 40 组历史前十全名单。Lovense 四期数据是用户已有 sem.3ue.com 界面的人工转录（C+），已核对范围与筛选，但不是本次取得的官方原始导出；Kinkly 查询返回不匹配的 eBay 演示数据，被排除。建议用官方导出复核竞争点。
7. 第三方全文 HTML 仅在本地 work/ 作分析缓存，没有打包。交付只含特征、链接、差异指标及必要元数据。没有浏览器授权参数、会话凭证或付费接口密钥。

## 原始输入

从 `/Users/who/Downloads/` 找到以下 8 个文件，原样复制到项目的 `work/rootcause/raw/`。没有改动原始输入。文件哈希与字段见 [source_audit.json](data/source_audit.json)。

```text
go3fun.co-organic.PagesV3-us-20260715-2026-10-10T02_36_53Z.csv
go3fun.co-organic.PagesV3-us-20261008-2026-10-10T02_25_53Z.csv
go3fun.co-organic.Positions-us-20260715-2026-10-10T02_28_28Z.csv
go3fun.co-organic.Positions-us-20261008-2026-10-10T02_28_07Z.csv
go3fun.co-organic.PositionChangesV2-us-20260815-2026-10-10T03_09_58Z.csv
go3fun.co-organic.PositionChangesV2-us-20260915-2026-10-10T03_03_09Z.csv
go3fun.co-backlinks.csv
3Fun- Couples & Singles Dating.xlsx
```

XLSX 表头为 Excel 第 9 行，按美国、2026-06 至 09 筛选并汇总。旧 Android App 的空值保留为空，不把它伪装成明确的零。

原始文件未随交付包重复分发；要从原始输入重跑，需提供这 8 个文件。已有加工数据足够离线重建图表、报告和阅读版。

## 运行环境

本机验证环境：Python 3.14.2，pandas 3.0.2、beautifulsoup4 4.14.3、openpyxl 3.1.5；curl；Node.js、sharp、marked（后两项来自已安装的工作区运行库）。不要求安装爬虫商业软件。文本分析不依赖 Excel 应用，不执行工作簿公式。

本机 Node 与模块路径：

```sh
task_node="/Users/who/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node"
task_modules="/Users/who/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules"
```

其他机器可用自身已安装的 Node、sharp、marked；设置 NODE_PATH 或采用正常项目依赖解析。路径是当前机器的配置，不是报告数据。

## 离线重建（使用随包加工数据）

在交付文件夹执行：

```sh
python3 scripts/synthesize.py
python3 scripts/serp_evidence.py
python3 scripts/evidence_tables.py
python3 scripts/charts.py
python3 scripts/write_reports.py
NODE_PATH="$task_modules" "$task_node" scripts/render_charts.cjs
NODE_PATH="$task_modules" "$task_node" scripts/build_reader.cjs
python3 scripts/validate.py --node "$task_node"
```

`serp_evidence.py` 是带来源说明的人工转录台账，**不会重新登录浏览器或假装重新获取历史数据**。`evidence_tables.py` 的归因评级与 `write_reports.py` 的叙述为编辑分析；报告表格从数据重建。策略文件是独立编辑稿，构建不会改写它。

## 从原始输入重算

`task_raw` 必须是只含上述 8 个输入的专用目录，不要直接指向包含无关 CSV 的 Downloads。以下从项目根目录运行；输出位置为当前交付目录。

```sh
task_raw="work/rootcause/raw"
task_out="outputs/3fun_root_cause/data"
python3 outputs/3fun_root_cause/scripts/audit.py --raw "$task_raw" --out "$task_out"
```

`data/public_suffix_list.dat` 是本次使用的固定 Public Suffix List，哈希记录在 summary.json。保持它可复算 1,453 个可注册域；更新它时域名结果可能变化，应记录版本，不能把更新后口径与旧约数混用。CSV 源行号以表头为第 1 行。

## 重新获取公开网页和档案（需要网络）

这些是可选重采集步骤。网站与档案可变化，成功数不保证与本研究快照一致；先备份已交付加工数据，重采集时不要把新结果假装成 10/12 快照。

```sh
python3 outputs/3fun_root_cause/scripts/collect_public.py --raw "$task_raw" --cache work/rootcause/html --out "$task_out"
python3 outputs/3fun_root_cause/scripts/archives.py --cache work/rootcause/archive --out "$task_out"
python3 outputs/3fun_root_cause/scripts/extract_archives.py --cache work/rootcause/archive --out "$task_out"
python3 outputs/3fun_root_cause/scripts/fetch_wayback.py --cache work/rootcause
python3 outputs/3fun_root_cause/scripts/compare_versions.py --cache work/rootcause/html --archive work/rootcause/archive --out "$task_out"
```

- 当前爬虫先读取 robots.txt，尊重允许范围；网络请求串行、间隔至少 1.1 秒、单次超时 25 秒，已有缓存优先。
- `archives.py` 查询 6 个重点 URL 的 Wayback CDX，以及 CC 2026-25/30/34/39 索引，保留失败。只提取匹配文章路径的记录。
- `extract_archives.py` 仅取索引指定 WARC 的 HTTP Range 片段，验证目标 URI 与抓取日期；失败不能算成功 HTML。本次有 65/66 条通过，1 条 best-ddlg-dating-apps 返回 503 未通过。
- 两个 Wayback 日期来自实际 CDX 返回，不是猜日期。`fetch_wayback.py` 为复取辅助；重取失败时不覆盖有效 HTML。原研究的存档时间及 WARC 哈希以 data/ 记录为准。
- `compare_versions.py` 对正文标准化文本、章节、Title/H1、图片标签数、链接目标、Canonical、robots 和 JSON-LD 做比较。它不是视觉像素比较，也没有比较全部图片内容。
- 然后按离线重建顺序生成报告与图表。新的源快照如改变计数，`validate.py` 的本次快照断言会失败，应先核对变化，不要为了通过而填补数据。

## 历史 SERP 手工导出

最优先补 femdom、kink、hotwife、cuckold 在 7、8、9 月的真实前十，再扩展其他词与 10 月初。

1. 单关键词打开 Keyword Overview，确认美国、桌面和历史月份；进入 SERP Analysis 导出完整 URL、名次及实际采样日（若提供）。Bulk Keyword Analysis 不是历史 SERP。
2. 原区域不能用时，从已证实历史结果确定竞争 URL，再在 Organic Rankings 选择**精确 URL**、历史月和**自然搜索**；在 Positions 过滤查询并导出，保留 URL 切换。
3. 页面标题、查询对象、URL 范围、国家、设备、月份、筛选必须匹配。若出现不相关演示数据、错误或空列表，记作失败，不记录排名。
4. 填 [historical_serp_export_template.csv](data/historical_serp_export_template.csv)，一条结果一行；保留源文件、导出时间、Position Type。空名次不填 0，月度点不加猜测日。
5. 新数据合并时，保留人工转录与官方导出来源类型，不悄悄覆盖来源；更新竞争图、H1/H4 判断及数据缺口。

## 图表目录

| 文件 | 内容 | 关键限制 |
| --- | --- | --- |
| 01_keyword_ranks | 10 查询四期 Organic 排名 | 缺失空白；URL 可切换 |
| 02_page_growth | 10 个高增长 URL 两期访问 | 无中间月插值 |
| 03_topic_contribution | 互斥主题净贡献 | slug 分类是分析规则 |
| 04_content_rank_timeline | 自报日期、独立档案、排名记录与更新窗口 | 日期性质分开；不是首次入前三日 |
| 05_actual_serp_comparison | femdom 与 Lovense 实际查询排名对照 | 一竞品、界面转录 C+、采样不同步 |
| 06_internal_link_network | 11 页 Hotwife/Cuckold 子图 | 历史可证边与仅当前边分开 |
| 07_hypothesis_matrix | 五假设证据覆盖 | 不是发生概率 |
| 08_control_comparison | 10+8+2 样本反例 | 非完全匹配实验 |

图表已生成 PNG 并检查 8 图总览与关键时间线。阅读版进行了 HTML 结构、资源与脚本语法检查；没有将这些检查描述成真实浏览器全流程交互验收。
