关键词挖掘与页面矩阵规划 (Keyword Miner)
核心原则
页面唯一依据是搜索需求,不是"看起来完整"。 不要为完整性做没人搜的页面。
用户搜的是非常具体的问题——codes、tier list、某个角色怎么获得。你要用不同页面分别承接这些搜索。
工具与数据获取方式
所有数据均通过本地浏览器实时抓取,使用 mcp_playwright-extension MCP 服务(server_name = mcp_playwright-extension),通过 run_mcp 调用。禁止使用 WebFetch/WebSearch 替代浏览器抓取,因为 Google Trends、SimilarWeb、Google 搜索结果等均依赖 JS 渲染或反爬,本地浏览器才能拿到真实数据。
核心工具调用规范:
# 导航到 URL
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_navigate",
args={"url": "https://..."})
# 抓取页面可访问性快照(用于交互/识别元素,推荐)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_snapshot",
args={}) # 可选: depth, target, filename
# 在页面执行 JS 提取数据(高效提取榜单/表格/文本)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_evaluate",
args={"function": "() => { /* 提取逻辑 */ return data; }"})
# 点击元素(target 来自 snapshot 的元素引用)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_click",
args={"element": "搜索按钮", "target": "..."})
# 填表单(如搜索框)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_fill_form",
args={"fields": [{"name":"搜索词","target":"...","type":"textbox","value":"gameplay trailer"}]})
# 等待页面加载/文本出现
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_wait_for",
args={"text": "某文本"}) # 或 {"time": 3}
# 截图(用于趋势曲线等需要肉眼判断的场景,可让用户辅助确认)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_take_screenshot",
args={"type": "png", "scale": "css", "fullPage": false})
# 抓取网络请求(用于抓 XHR/API 数据)
run_mcp(server_name="mcp_playwright-extension", tool_name="browser_network_requests",
args={"static": false, "filter": "/api/.*"})
抓取流程通用模式:navigate → wait_for → snapshot/evaluate → (必要时)click/fill_form → evaluate
关键技巧:
- 优先用
browser_evaluate执行 JS 直接提取结构化数据(如搜索结果域名列表、下拉词),比 snapshot 更精炼 - 用
browser_snapshot拿到元素引用(ref),再用browser_click/browser_fill_form交互 - Google Trends 曲线、SimilarWeb 数据等需要肉眼判断的场景,用
browser_take_screenshot截图 - 抓 API 数据时,先
browser_navigate触发请求,再browser_network_requests过滤
前置条件
用户需提供:
- 游戏主词(已确定的游戏名称,通常由 yxz-hot-word-miner 技能输出)
- 可选:练习词或子词(用于拓展搜索范围)
执行流程
第一步:从 3 个来源挖掘搜索需求
来源 1:Google 下拉词
在 Google 搜索框输入游戏主词,记录自动补全的下拉建议——这是用户真实输入的搜索表达。
抓取方法(playwright-extension,实测有效避免缓存):
# 1. 直接访问搜索词对应的搜索结果页(关键:不要从 Google 主页开始输入,否则会命中缓存)
run_mcp("mcp_playwright-extension", "browser_navigate",
args={"url": "https://www.google.com/search?q={搜索词URL编码}&hl=en"})
# 2. 等待页面加载
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 3})
# 3. 用 snapshot 定位搜索框 combobox(搜索框中已预填搜索词,无需 Clear 或重新输入)
run_mcp("mcp_playwright-extension", "browser_snapshot", args={})
# 4. 点击搜索框 combobox,触发下拉建议
run_mcp("mcp_playwright-extension", "browser_click", args={
"element": "Search box combobox",
"target": "{搜索框combobox的ref}"
})
# 5. 等待 8 秒(关键:等待时间不足会命中浏览器缓存,返回旧的下拉建议)
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 8})
# 6. 再次 snapshot 提取下拉建议词(下拉框会出现在 combobox 下的 listbox 中)
run_mcp("mcp_playwright-extension", "browser_snapshot", args={})
# 从 snapshot 中找 listbox 下的 option 元素,记录每个 option 的文本
关键注意事项(避免缓存):
- 必须直接访问搜索结果页(URL 含
search?q=词),不要从 Google 主页开始输入 - 等待时间必须 ≥ 8 秒,等待 2-5 秒会命中浏览器缓存,返回旧数据
- 搜索框中已预填搜索词,不要 Clear 清空,直接点击 combobox 即可触发
- 缓存特征:下拉词只有 3-4 个且都是搜索词自身的变体(如搜"big walk wiki"返回"big walk wiki/big walk game wiki/big walk pc/big walk")
- 实时数据特征:下拉词有 8-10 个,涵盖不同维度(如搜"big walk wiki"返回"release date/price/game/trailer/cross platform/ps5/how many players/steam")
技巧:可访问不同前缀的搜索结果页(如 {游戏主词} guide、{游戏主词} how to、{游戏主词} codes、{游戏主词} wiki、{游戏主词} crossplay)触发更多下拉词。
来源 2:Google Trends 相关词
访问 Google Trends,查看游戏主词的"相关查询"区域,通常能获取 10-20 个相关关键词。
抓取方法(playwright-extension):
# 1. 导航到 Google Trends 探索页(直接带参数 URL)
# 实测:前 1-2 个词直接 URL 可用,第 3 个词起可能触发 reCAPTCHA
# reCAPTCHA 对策:先 navigate 落地页 https://trends.google.com/trends/explore?hl=zh-CN 重建会话
run_mcp("mcp_playwright-extension", "browser_navigate", args={
"url": "https://trends.google.com/trends/explore?q={游戏词URL编码}&date=today%201-m&hl=zh-CN"
})
# 2. 等待趋势数据加载(Trends 渲染较慢,建议等 5-8 秒)
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 6})
# 3. 提取页面全文(含相关查询、平均值、区域 Top 5)
run_mcp("mcp_playwright-extension", "browser_evaluate", args={
"function": "() => document.body.innerText.substring(0, 4000)"
})
# 返回文本中找"相关查询"区块,提取搜索量上升/排名靠前的相关词
# 若返回文本很短(<300字符)且无"平均值"→ 说明该词搜索热度极低
Trends reCAPTCHA 对策(实测有效):
若带 q= 参数的 URL 触发 reCAPTCHA("Oops! There was a problem displaying this page"),按以下步骤:
- 先 navigate 落地页
https://trends.google.com/trends/explore?hl=zh-CN(无参数) - 用
browser_type在搜索框输入游戏名 - 用
browser_evaluate点击下拉建议项中的"视频游戏"类型 - URL 会变成
?q=/g/11xxxx(Knowledge Graph ID),cookie 已通过验证 - 再 navigate 带
q={KGID}&date=today 1-m的 URL
来源 2.5(首选):SEMrush 中文版细分词 / 问题词
SEMrush 中文版是 KD / Volume / 细分词的首选数据源(需已登录 Semrush 账号,URL 模板 https://zh.semrush.com/analytics/keywordoverview/?q={词}&db=us)。首屏返回 5 个细分词(含 KD%)+ 5 个问题型长尾词(含 KD%)+ 关键词聚类群组,是页面矩阵长尾词的主要来源。
抓取方法(提取函数见 yxz-hot-word-miner 验证 2):
browser_navigate打开 SEMrush 关键词概览 URL(自动补&db=us)browser_wait_for等待加载,再用browser_evaluate提取主词 KD% / 美国搜索量 / 全球搜索量 / 意图 / 细分词 KD / 问题词 KD / 聚类群组
SEMrush 数据要点(用于页面矩阵长尾词挖掘):
- 主词 KD%(百分比制):< 30% 容易 / 30-50% 中等 / > 50% 困难,作首选结论
- 细分词 KD%:直接给出每个长尾词的难度,优先挑 KD% ≤ 30 的做内页
- 问题型长尾词:直接反映用户真实搜索意图(how to / best / vs 等),是攻略页的最佳候选
- 关键词聚类群组:揭示语义相关的词族,用于扩展导航页分类
来源 3(可选补充):SimilarWeb Pro 搜索词
三源优先级:KD / Volume / 细分词以 SEMrush 中文版(首选,需登录)→ Ubersuggest(验证,无需登录)→ SimilarWeb Pro(本步骤,可选) 三级获取。本步骤是可选的 SimilarWeb Pro 补充源,仅在已登录 Pro 账号、且前两者数据不足时使用,其"领先者域名列"对竞争格局判断很有价值。
在 SimilarWeb Pro 查看游戏相关词的搜索词历史数据(需已登录 Pro 账号):
⚠️ 实测结论:SimilarWeb 免费版关键词分析页已于 2026-07-31 下线(返回 403)。改用 SimilarWeb Pro 版(需已登录 Pro 账号):
# SimilarWeb Pro 关键词生成器(实测可用,2026-08-06)
# tab=phraseMatch 语句匹配 / tab=related 相关关键词 / tab=questions 问题查询
run_mcp("mcp_playwright-extension", "browser_navigate", args={
"url": "https://pro.similarweb.com/#/digitalsuite/acquisition/findkeywords/keyword-generator-tool/999/28d?searchEngine=google&keyword={游戏词URL编码}&webSource=Total&isWWW=*&tab=phraseMatch"
})
# 等待数据加载(表格需要 6-10 秒)
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 8})
# 提取表格数据(SimilarWeb 用 div 布局,数据按列排列)
# 关键:先定位第一个意图行(INFO/NAV/TRANSAC等),再反推 KD 列位置
run_mcp("mcp_playwright-extension", "browser_evaluate", args={
"function": "() => { const kw = '{游戏词}'; const text = document.body.innerText; const lines = text.split('\\n').filter(l => l.trim()); const kwStart = lines.findIndex((l, i) => l === kw && i > 100); if (kwStart === -1) return { error: 'keyword not found' }; let firstIntentIdx = -1; for (let i = kwStart + 400; i < kwStart + 700; i++) { const l = lines[i]; if (l === 'INFO' || l === 'NAV' || l === 'TRANSAC.' || l === 'INVESTIGATIONAL' || l === 'COMMERCIAL') { firstIntentIdx = i; break; } } if (firstIntentIdx === -1) return { error: 'intent not found' }; const kdStart = firstIntentIdx - 100; const kwList = lines.slice(kwStart, kwStart + 10); const volList = lines.slice(kwStart + 100, kwStart + 110); const kdList = lines.slice(kdStart, kdStart + 10); const intentList = lines.slice(firstIntentIdx, firstIntentIdx + 10); return { kwList, volList, kdList, intentList }; }"
})
# 返回:kwList(关键词)、volList(28天搜索量)、kdList(KD难度)、intentList(意图类型)
SimilarWeb Pro 数据要点:
- 28天搜索量:给出绝对月搜量
- 细分关键词数:语句匹配模式返回数百到数千个细分词
- KD 难度:<30 新手可做,30-40 需谨慎,>40 不建议
- 意图类型:INFO(信息型)、NAV(导航型)、TRANSAC.(交易型)
- 领先者列:显示每个关键词排名最靠前的域名,直接判断竞争格局
降级方案:SimilarWeb Pro 无数据/未登录时,依次降级:
- Ubersuggest(获取 Volume/SD/细分词):
run_mcp("mcp_playwright-extension", "browser_navigate", args={ "url": "https://app.neilpatel.com/en/ubersuggest/keyword_ideas?keyword={游戏词URL编码}&locId=2840" }) run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 10}) run_mcp("mcp_playwright-extension", "browser_evaluate", args={ "function": "() => { const rows = document.querySelectorAll('tbody tr, table tr'); return [...rows].slice(0, 30).map(tr => [...tr.querySelectorAll('td')].map(td => td.innerText.trim().substring(0, 50))).filter(arr => arr.length > 0); }" }) - Google "People also ask"(免费,见下方补充来源)
- Google Trends 相关查询(已在来源 2 获取)
补充来源:Google "People also ask/search for"(实测有效,必查)
一个 Google 搜索就能从 "People also ask" 拿到 4-8 个真实用户问题,从 "People also search for" 拿到 8 个相关搜索词:
# 1. 导航到 Google 搜索(加 guide 触发更多攻略类问题)
run_mcp("mcp_playwright-extension", "browser_navigate", args={
"url": "https://www.google.com/search?q={游戏词URL编码}+guide&hl=en"
})
# 2. 等待结果加载
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 3})
# 3. 提取页面全文(含 "People also ask" 和 "People also search for" 区块)
run_mcp("mcp_playwright-extension", "browser_evaluate", args={
"function": "() => document.body.innerText.substring(0, 4000)"
})
# 从返回文本中找 "People also ask" 区块(4-8 个真实用户问题)
# 从返回文本中找 "People also search for" 区块(8 个相关搜索词)
Google 搜索 IP 被标记对策: 若 Google 搜索出现 429 + /sorry/ 重定向(IP 被标记),让用户切换网络环境(更换 IP / 关闭代理 / 使用移动热点)后重试。不要降级到 Bing——Google 才是主要流量来源。
第二步:整理关键词清单
将收集到的所有关键词整理成结构化清单,包含:
- 关键词本身
- 搜索意图描述
- 需求类型分类
需求分类标准:
| 类型 | 说明 | 示例 | 适合页面 |
|---|---|---|---|
| 通用需求 | 所有玩家都会关心的问题 | 游戏介绍、怎么玩、下载方式 | 首页 |
| 个性需求 | 特定玩家群体的细分需求 | 角色攻略、装备获取、兑换码 | 内页 |
分类原则:
- 能用一句话回答的通用问题 → 通用需求 → 适合做首页内容
- 需要专门页面详细解答的细分问题 → 个性需求 → 适合做内页
- 若细分角色/道具很多,做统一导航页批量展示,不必手动逐个做独立页面
第三步:生成关键词清单文档
输出格式要求:
# 关键词挖掘清单 - {游戏主词}
## 通用需求关键词
| 序号 | 关键词 | 搜索意图 | 搜索来源 | 预估热度 |
|------|--------|----------|----------|----------|
| 1 | xxx | xxx | Google下拉/Trends/SEMrush/Ubersuggest/SimilarWeb/People also ask | 高/中/低 |
## 个性需求关键词
| 序号 | 关键词 | 搜索意图 | 搜索来源 | 预估热度 |
|------|--------|----------|----------|----------|
| 1 | xxx | xxx | Google下拉/Trends/SEMrush/Ubersuggest/SimilarWeb/People also ask | 高/中/低 |
## 统计汇总
- 通用需求关键词数量:X 个
- 个性需求关键词数量:X 个
- 总计:X 个(至少 10 个)
第 3.5 步:意图聚类与页面合并闸门(规划矩阵前必跑)
关键词清单里天然存在同义词、同意图词、上下位词。如果把每个词直接映射成一页,必然规划出语义重复的页面。
合并必须在这一步完成,不能留到 game-info-collector 阶段——那时素材都收完了才发现两页讲同一件事,返工成本是这里的十倍以上(要重收素材、重挑视频、重写矩阵、重改站点结构)。
三道闸门依次过,过不了的词合并进同一页。
闸门 A:SERP 重叠检测(关键词层,判定意图是否相同)
判断两个词是不是同一个搜索意图,最可靠的依据是 Google 自己的答案——同意图的词,搜索结果首页会高度重合。
只对嫌疑词对做(不用全量两两比)。嫌疑对的识别标准:词干相同、SEMrush 聚类在同一群组、或一个词是另一个的上位词。
# 对词 A、词 B 分别抓取 Top 10 结果 URL
run_mcp("mcp_playwright-extension", "browser_navigate", args={
"url": "https://www.google.com/search?q={词URL编码}&hl=en&num=10"})
run_mcp("mcp_playwright-extension", "browser_wait_for", args={"time": 3})
run_mcp("mcp_playwright-extension", "browser_evaluate", args={
"function": "() => [...document.querySelectorAll('a[href^=\"http\"] h3')].slice(0,10).map(h => { const a = h.closest('a'); try { return new URL(a.href).hostname + new URL(a.href).pathname; } catch(e) { return a.href; } })"
})
# 比对两次返回的 URL 列表,统计重合数量
| 重叠 URL 数 | 判定 | 处理 |
|---|---|---|
| ≥ 3 个 | 同一搜索意图 | 必须合并为一页(行业通行阈值) |
| 1-2 个 | 相关但意图不同 | 各自成页,但需强内链 |
| 0 个 | 完全独立 | 各自成页 |
闸门 B:实体计数(决定「导航页 + 详解页」能不能拆两层)
只要打算规划「导航页 + 详解页」两层结构,必须先数清这个主题下游戏里到底有几个实体。
这一步在规划期完全可查,不需要等素材收集(1-2 次抓取即可):
- Steam 商店页的描述与特色列表(
hot-word-miner阶段通常已抓过) - Google 搜
{游戏} all characters list/all maps/all weapons,看攻略站列了几个 - 官方 wiki / Fandom 分类页的条目数
| 实体数量 | 结论 |
|---|---|
| < 8 个 | 只做一页,导航与详解合并(详解作为页内分节) |
| 8-20 个 | 一个导航页 + 重点实体的少量详解页 |
| > 20 个 | 导航页 + 独立详解页,可交给 yxz-bulk-page-factory 批量生成 |
导航页的存在前提是"条目多到需要索引"。4 个条目让用户多点一次纯属多余,而且会导致两页反复讲同一批实体,构成关键词自噬。
闸门 C:游戏机制适配(排除根本不成立的页面)
某些页面类型在特定游戏里压根不成立,规划期查一眼 Steam 描述就能排除:
| Steam 描述中出现 | 不成立的页面 | 原因 |
|---|---|---|
| procedurally generated / roguelike / randomized | 地图坐标索引页、固定路线攻略 | 没有固定地图,只能做"地点类型/空间结构"一页 |
| 无武器系统 / tool-based / 只有工具道具 | 武器 tier list、best weapons 排行 | 没有可排序的武器池 |
| 无 codes / 兑换码机制 | codes 兑换码页 | 内容不存在 |
| 单机无联机 | 联机/组队/跨平台页 | 内容不存在 |
⚠️ 务必区分「页面不成立」与「答案是否定的」:
is {游戏} crossplay即使答案是"不支持",仍是高频搜索词 → 该做直答页(Google 对这类问题偏好直答页,合并会丢精准词)- 而"地图坐标索引"在程序化生成的游戏里是内容本身不存在 → 不该做
闸门 D:反向检查——有没有一页该拆开
合并之外还要反向查:有没有一页混装了多类互相独立的搜索需求?
典型案例:update / 更新日志页常混装「版本 patch notes」与「崩溃/黑屏/闪退修复」。后者是完全独立的高需求长尾词族({游戏} crash fix / not launching / black screen),应拆出独立的 /troubleshooting 页。新游戏发售初期,故障修复类词的搜索量往往高于 patch notes 本身。
闸门输出:合并记录表
## 意图聚类与合并记录
| 原关键词组 | 闸门判定 | 判定依据 | 处理结果 |
|-----------|---------|---------|---------|
| {游戏} characters / {游戏} classes | 闸门 A:SERP 重叠 6/10;闸门 B:仅 4 个实体 | 同意图 + 实体不足 8 | 合并为 1 页 `/characters` |
| {游戏} map / {游戏} all locations | 闸门 C:程序化生成 | 无固定地图 | 合并为 1 页 `/map` |
| {游戏} crossplay / {游戏} controller | 闸门 A:SERP 重叠 1/10 | 意图独立 | **不合并**,各自成页 + 内链 |
| {游戏} update | 闸门 D:混装两类需求 | 故障修复是独立词族 | **拆分**为 `/update` + `/troubleshooting` |
**合并结果**:候选 X 页 → 合并 Y 组 → 拆分 Z 页 → 最终 N 页
第四步:规划页面矩阵
根据已过合并闸门的关键词清单,规划每个关键词对应的页面类型。
页面类型定义:
| 页面类型 | 承接内容 | 说明 |
|---|---|---|
| 首页 | 主游戏词 | 解决"这是什么游戏、怎么玩、有哪些核心内容" |
| 导航页 | 角色/道具/分类索引 | 批量展示,不必手动逐个做独立页面 |
| 攻略页 | 长尾问题词 | 具体攻略型内容,如"XX角色怎么获得" |
| 物品页 | 物品/道具详情 | 物品获取、属性、使用方法 |
| 角色页 | 角色详情 | 角色属性、技能、获取方式 |
| 其他内页 | 其他长尾词 | 根据搜索需求灵活创建 |
输出格式:
# 页面矩阵规划 - {游戏主词}
## 页面规划表
| 页面序号 | 页面类型 | 对应关键词 | 解决用户问题 | 承接的合并词 | 备注 |
|----------|----------|------------|--------------|--------------|------|
| 1 | 首页 | {游戏主词} | 这是什么游戏、怎么玩 | — | 核心入口页 |
| 2 | 导航页 | 角色列表/道具列表 | 查找所有角色/道具 | classes / roles(闸门A合并) | 批量索引,实体 >8 才拆详解页 |
| 3 | 攻略页 | XX角色攻略 | 如何获得XX角色 | — | 长尾词承接 |
| ... | ... | ... | ... | ... | ... |
> **「承接的合并词」列必填**:记录本页通过闸门 A/B/C 吸收了哪些同意图词。这一列是给 `game-info-collector` 和 `game-site-builder` 看的——收素材时要一并覆盖这些词,写页面时要在正文自然包含它们。
## 页面统计
- 首页:X 个
- 导航页:X 个
- 攻略页:X 个
- 物品页:X 个
- 角色页:X 个
- 其他内页:X 个
- **总计页面数**:X 个
第五步:绘制站点结构
生成站点结构示意图(使用文本树或 Mermaid 格式):
graph TD
A[首页 - {游戏主词}] --> B[导航页 - 角色列表]
A --> C[导航页 - 道具列表]
A --> D[攻略页 - 新手入门]
B --> B1[角色页 - 角色1]
B --> B2[角色页 - 角色2]
C --> C1[物品页 - 物品1]
D --> D1[攻略页 - XX怎么玩]
D --> D2[攻略页 - XX兑换码]
或文本树格式:
首页 ({游戏主词})
├── 导航页:角色列表
│ ├── 角色页:角色A
│ ├── 角色页:角色B
│ └── ...
├── 导航页:道具列表
│ ├── 物品页:道具A
│ └── ...
├── 攻略页:新手入门
├── 攻略页:XX角色攻略
└── 攻略页:XX兑换码
页面设计原则
- 首页承接主游戏词,解决"这是什么游戏、怎么玩、有哪些核心内容"
- 内页承接具体长尾词,精准匹配搜索需求
- 细分角色/道具多时,做统一导航页,不必手动逐个做独立页面
- 页面只从搜索需求反推,不做没人搜的页面
- 第一个版本只做最核心的页面,不要一次性规划所有可能页面
- 新手站最小页面集:首页 + Guide(指南攻略)+ 10-20 个攻略型长尾问题页
- 一个搜索意图只能有一个页面(第 3.5 步闸门 A)。两页抢同一批 SERP = 关键词自噬,Google 会挑一页排名、压制另一页,等于白做
- 两层结构(导航页 + 详解页)必须先数实体(第 3.5 步闸门 B)。实体 < 8 个直接合并为一页——这是页面重复最高发的来源
- 页面类型要匹配游戏机制(第 3.5 步闸门 C)。程序化生成的游戏没有地图索引页;没有武器系统的游戏没有 tier list 页
- 合并的反面是拆分(第 3.5 步闸门 D)。一页混装多类独立需求同样有害,典型是"更新日志"里塞崩溃修复
批量承接这些页:页面矩阵定稿后,若需要一次铺几十个内页,交给
yxz-bulk-page-factory——它直接读这张矩阵表批量生成内页(提示词生产线 + 脚本挂载 + 防灌水闸门)。单篇内容先跑顺,再谈批量。
浏览器抓取要点
- 统一用
mcp_playwright-extension:所有数据均通过run_mcp调用本地浏览器实时抓取,禁止用 WebFetch/WebSearch 替代(JS 渲染/反爬拿不到真实数据) - 反爬场景优先截图:Google Trends、SimilarWeb 等有反爬,JS 提取可能失败,此时用
browser_take_screenshot截图,从图中读取数据 - 趋势判断优先截图:Google Trends 的曲线形态靠肉眼最准
- 结构化数据优先 evaluate:Google 搜索结果、下拉词等结构化数据,用
browser_evaluate执行 JS 提取最精炼 - 等待加载:每次
browser_navigate后必须browser_wait_for(等文本或等几秒),避免抓到空页面 - 页面选择器可能变化:示例中的 CSS 选择器可能随网站改版失效,抓取失败时用
browser_snapshot重新定位元素 - URL 编码:游戏词拼到 URL 时必须
encodeURIComponent,避免空格/特殊字符破坏 URL - 一个浏览器实例复用:playwright-extension 共享一个浏览器会话,多个查询顺序执行(navigate→抓取→下一个 navigate),不要并行
实战踩坑教训
- Google Trends reCAPTCHA:带
q=参数的 explore URL 可能触发 reCAPTCHA。对策:先 navigate 落地页https://trends.google.com/trends/explore?hl=zh-CN(无参数)重建会话,再 navigate 带参数 URL。详见上方"来源 2"的 reCAPTCHA 对策。 - Trends 连续查询触发 reCAPTCHA:第 1-2 个词直接 URL 可正常加载,第 3 个词起可能触发。对策:间隔 30 秒重试,或用落地页 + 交互式入页方式。
- Google 搜索
div.g选择器失效:提取首页竞品时document.querySelectorAll('div.g')可能返回空数组。对策:直接用browser_evaluate提取document.body.innerText.substring(0, 4000),从纯文本中解析。 - Google 搜索 IP 被标记:可能出现 429 + /sorry/ 重定向。对策:让用户切换网络环境(更换 IP / 关闭代理 / 使用移动热点)后重试。不要降级到 Bing。
- SimilarWeb 免费版已下线:
similarweb.com/seo/keyword-analysis/返回 403。必须用 SimilarWeb Pro 版(pro.similarweb.com),或降级到 Ubersuggest。 - SimilarWeb Pro 表格提取必须用"意图列反推法":SimilarWeb Pro 用 div 布局,数据按列排列,列偏移量因词而异。正确方法:先找主词位置(kwStart),再从 kwStart+400 到 kwStart+700 范围内搜索第一个意图值(INFO/NAV/TRANSAC.等),该位置往前 100 行即为 KD 列起始位置。详见上方代码示例。
- Ubersuggest SD 对专门站竞争严重低估:SD 只看反链数,不衡量专门站数量。SD 低不代表竞争小,只代表反链少。
- Google "People also ask" 是细分需求金矿:一个 Google 搜索就能拿到 4-8 个真实用户问题 + 8 个相关搜索词,比 SimilarWeb 细分关键词列表更直接、更免费、更真实。
- 至少整理 10 个细分关键词:关键词要具体到用户问题层面,不只写大词。若 3 个来源合计不足 10 个,用不同前缀(guide/how to/best/codes/wiki)多次触发 Google 下拉词。
- Google Trends 相对热度不可跨查询比较:每次查询的 0-100 是同一次查询内的相对值。不要拿不同查询的绝对值对比。
- Google 下拉词缓存陷阱(重要):从 Google 主页输入搜索词、或等待时间不足(<8秒)、或 Clear 后重新输入,都会命中浏览器缓存,返回旧的下拉建议(特征:只有 3-4 个词且都是搜索词自身变体)。正确做法:直接访问
https://www.google.com/search?q={词}&hl=en搜索结果页 → 点击搜索框 combobox → 等待 ≥8 秒 → snapshot 提取 listbox 下的 option。实测"big walk wiki"缓存返回 4 个自身变体,实时返回 8 个不同维度词(release date/price/game/trailer 等)。 - 页面合并必须在规划期做完,不能拖到素材收集后(重要,GRAIN ROT 实战教训):GRAIN ROT 规划了 18 页,素材全部收完后跑重叠检测才发现
characters+characters-guide(Jaccard 0.351)与map+map-guide(0.296)两组必须合并——这两组的合并依据在规划期就完全可得(游戏只有 4 种 vessel、官方标注 procedurally shifting dungeons),却因为规划时没有闸门 B/C,白收了 2 页素材、白挑了 2 个视频、白提了 2 份字幕。先数实体、先查机制,再画矩阵。 - 判断该不该合并,决定性依据是游戏实体数量,不是文本相似度:相似度只用来定位嫌疑对。各攻略页天然共享同一批游戏术语,Jaccard 高不代表意图重复(如
crossplay×controller达 0.23 但意图完全独立,合并会丢词)。先看实体数量与机制,再看 SERP 重叠,最后才参考相似度数字。 - 规划时就要给每页指定不同的参考视频:若两页在矩阵里指向同一个 YouTube 视频,素材阶段提取的字幕会以大段相同文本落进两页,直接制造重复内容。矩阵定稿时按页检查视频唯一性,比事后替换省事得多。
输出文件
执行完成后生成以下文件:
- 关键词清单文档:
{日期}-{游戏主词}-关键词清单.md - 页面矩阵规划文档:
{日期}-{游戏主词}-页面矩阵.md
关键词清单文档结构
# 关键词挖掘清单 - {游戏主词}
> 挖掘日期:{日期}
> 游戏主词:{游戏主词}
> 数据来源:Google 下拉词 / Google Trends / SEMrush / Ubersuggest / SimilarWeb Pro / Google People also ask
## 通用需求关键词
| 序号 | 关键词 | 搜索意图 | 搜索来源 | 预估热度 |
|------|--------|----------|----------|----------|
| 1 | xxx | xxx | xxx | 高/中/低 |
## 个性需求关键词
| 序号 | 关键词 | 搜索意图 | 搜索来源 | 预估热度 |
|------|--------|----------|----------|----------|
| 1 | xxx | xxx | xxx | 高/中/低 |
## 统计汇总
- 通用需求关键词数量:X 个
- 个性需求关键词数量:X 个
- 总计:X 个
页面矩阵规划文档结构
# 页面矩阵规划 - {游戏主词}
> 规划日期:{日期}
> 游戏主词:{游戏主词}
> 基于关键词清单:{清单文件名}
> 合并闸门:已跑(候选 X 页 → 合并 Y 组 → 拆分 Z 页 → 最终 N 页)
## 实体计数与机制核查(闸门 B / C 依据)
| 主题 | 实体数量 | 数据来源 | 两层结构结论 |
|------|----------|----------|--------------|
| 角色/职业 | X 个 | Steam 描述 / all characters list | <8 → 合并为一页 |
| 地图/地点 | 程序化生成 | Steam "procedurally generated" | 无坐标索引页,只做一页 |
| 武器/道具 | X 个 | all weapons 攻略站 | ... |
## 意图聚类与合并记录
| 原关键词组 | 闸门判定 | 判定依据 | 处理结果 |
|-----------|---------|---------|---------|
| ... | ... | ... | ... |
## 页面规划表
| 页面序号 | 页面类型 | 对应关键词 | 解决用户问题 | 承接的合并词 | 参考视频 | 备注 |
|----------|----------|------------|--------------|--------------|----------|------|
| 1 | 首页 | {游戏主词} | 这是什么游戏、怎么玩 | — | {视频ID} | 核心入口页 |
| ... | ... | ... | ... | ... | ... | ... |
> 「参考视频」列需保证**全表不重复**,避免素材阶段字幕重复落页。
## 页面统计
(按类型统计页面数量)
## 站点结构示意图
```mermaid
graph TD
A[首页] --> B[导航页]
A --> C[攻略页]
...