[{"data":1,"prerenderedAt":552},["ShallowReactive",2],{"blog-keyword-library-four-tables":3,"blog-prev-keyword-library-four-tables":109,"blog-next-keyword-library-four-tables":359},{"id":4,"title":5,"author":6,"body":7,"canonical":93,"category":94,"cover":93,"date":95,"description":96,"draft":97,"extension":98,"keywords":93,"meta":99,"navigation":100,"noindex":97,"ogImage":93,"path":101,"seo":102,"seoDescription":93,"seoTitle":93,"stem":103,"tags":104,"updated":93,"__hash__":108},"blog\u002Fblog\u002Fkeyword-library-four-tables.md","把两万个关键词压成四张表，我们的词库分层法","元析智能",{"type":8,"value":9,"toc":82},"minimark",[10,14,18,21,24,27,30,33,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79],[11,12,13],"p",{},"词库建得越大，越没人用。我们的做法是反过来的：两万一千个词进来，最后只留四张表，加起来不到 1200 个词。四张表各有用途，每周五更新一次，谁都能打开看懂。",[15,16,17],"h2",{"id":17},"四张表分别放什么",[11,19,20],{},"第一张是核心词，10 到 20 个，决定首页、导航和产品页的定位。第二张是页面词，每个词绑定一个确定的 URL。第三张是长尾池，不绑页面，按主题挂着。第四张是排除词，写明为什么不写。",[11,22,23],{},"四张表之外，别的词都进回收站。需要时再翻，不占位置。",[15,25,26],{"id":26},"核心词这张表最重要",[11,28,29],{},"核心词是客户会用来描述你这个品类的词，通常不超过 20 个。它决定首页标题、导航结构，也决定你未来两年跟谁竞争。",[11,31,32],{},"这张表我们半年才动一次。动一次要重新看竞品和客户说法，不是加一个词那么简单。",[15,34,36],{"id":35},"页面词要写到-url-一级","页面词要写到 URL 一级",[11,38,39],{},"第二张表每行必须有一个 URL，没有 URL 的词打回去。这张表是给排期用的，写稿的人拿到行就能开工。",[11,41,42],{},"我们 2025 年 10 月统计过，这张表里 68% 的词已经有对应页面，剩下 32% 就是下个季度的选题来源。",[15,44,45],{"id":45},"长尾池只记三个字段",[11,47,48],{},"词、意图、归属主题。不记搜索量，不记难度分。长尾池会持续变大，字段一多就没人维护。",[11,50,51],{},"每周五我们从搜索后台导一次新查询，人工过一遍，能用的扔进池子，不能用的进排除词表。",[15,53,54],{"id":54},"排除词表是被低估的一张",[11,56,57],{},"排除词表写清楚“免费、破解、下载、招聘、外包”这一类，也写下“这个词跟我们的产品无关”“这个词搜的人不会买”。",[11,59,60],{},"新同事接手时不看这张表，会把去年删掉的词重新挖回来。我们遇到过两回。",[15,62,63],{"id":63},"我们走过的弯路",[11,65,66],{},"2025 年上半年，我们把词库按 20 个行业分成 20 张表，做得很规整。结果三个月后没人打开，因为找不到该看哪张。",[11,68,69],{},"下半年改成四张表，第一周就有人主动用了。分类不是越细越好，是让人一眼知道去哪张表里找东西。",[15,71,72],{"id":72},"四张表之间怎么流动",[11,74,75],{},"新词默认进长尾池，被证明有承接价值才升进页面词表，被证明没人搜才降进排除词表。每个月做一次升降，只动 20 到 30 个。",[11,77,78],{},"这个流动过程本身就是选题会。词往上走，说明有活儿要干；词往下走，说明以前判断错了。",[11,80,81],{},"词库不是资料，是排期表的上游。上游乱，下游一定乱。",{"title":83,"searchDepth":84,"depth":84,"links":85},"",2,[86,87,88,89,90,91,92],{"id":17,"depth":84,"text":17},{"id":26,"depth":84,"text":26},{"id":35,"depth":84,"text":36},{"id":45,"depth":84,"text":45},{"id":54,"depth":84,"text":54},{"id":63,"depth":84,"text":63},{"id":72,"depth":84,"text":72},null,"SEO","2025-11-19","词库的价值在删不在存。两万一千个词经过三层过滤，最后只留四张表：核心词、页面词、长尾池、排除词。每张表有明确用途和负责人，每周五更新一次。",false,"md",{},true,"\u002Fblog\u002Fkeyword-library-four-tables",{"title":5,"description":96},"blog\u002Fkeyword-library-four-tables",[105,106,107],"词库搭建","关键词研究","内容排期","0X3kYHpm_KvMf_jzr50-tPVqtF9vZm2Trw36Yh0kMNk",{"id":110,"title":111,"author":6,"body":112,"canonical":93,"category":347,"cover":93,"date":348,"description":349,"draft":97,"extension":98,"keywords":93,"meta":350,"navigation":100,"noindex":97,"ogImage":93,"path":351,"seo":352,"seoDescription":93,"seoTitle":93,"stem":353,"tags":354,"updated":93,"__hash__":358},"blog\u002Fblog\u002Fcls-image-dimension-fix.md","给图片和嵌入组件写死尺寸，CLS 一周从零点三降到零点零九",{"type":8,"value":113,"toc":340},[114,117,121,124,192,203,206,210,213,302,309,312,315,318,321,324,327,330,333,336],[11,115,116],{},"上个月我们给一个开发者工具站做 CLS 整改，从 0.31 降到 0.09，用了一周。动的是 168 个没写尺寸的图片和 6 个嵌入组件。方法不新鲜，难的是把全站扫干净，一个都别漏。",[15,118,120],{"id":119},"图片给每个-img-补上宽高","图片：给每个 img 补上宽高",[11,122,123],{},"CLS 的根源是浏览器不知道元素最终多大，等内容到了再撑开。宽高属性是成本最低的修法，现代浏览器会拿这两个数自动算宽高比、预留空间。",[125,126,130],"pre",{"className":127,"code":128,"language":129,"meta":83,"style":83},"language-html shiki shiki-themes github-light github-dark","\u003Cimg src=\"dashboard.webp\" width=\"1440\" height=\"810\" alt=\"产品后台截图\" loading=\"lazy\">\n","html",[131,132,133],"code",{"__ignoreMap":83},[134,135,138,142,146,150,153,157,160,162,165,168,170,173,176,178,181,184,186,189],"span",{"class":136,"line":137},"line",1,[134,139,141],{"class":140},"sVt8B","\u003C",[134,143,145],{"class":144},"s9eBZ","img",[134,147,149],{"class":148},"sScJk"," src",[134,151,152],{"class":140},"=",[134,154,156],{"class":155},"sZZnC","\"dashboard.webp\"",[134,158,159],{"class":148}," width",[134,161,152],{"class":140},[134,163,164],{"class":155},"\"1440\"",[134,166,167],{"class":148}," height",[134,169,152],{"class":140},[134,171,172],{"class":155},"\"810\"",[134,174,175],{"class":148}," alt",[134,177,152],{"class":140},[134,179,180],{"class":155},"\"产品后台截图\"",[134,182,183],{"class":148}," loading",[134,185,152],{"class":140},[134,187,188],{"class":155},"\"lazy\"",[134,190,191],{"class":140},">\n",[11,193,194,195,198,199,202],{},"有了这两个属性，图片下载前就能按 16:9 占位。响应式图片再配上 ",[131,196,197],{},"sizes"," 和 ",[131,200,201],{},"srcset","，占位比例依然成立。",[11,204,205],{},"查法：跑一遍全站爬虫，把没有 width 和 height 的 img 列出来。我们这个站 312 张图里有 168 张缺尺寸，主要来自博客正文和客户案例页，编辑器上传时没做校验。",[15,207,209],{"id":208},"嵌入组件iframe-也要占位","嵌入组件：iframe 也要占位",[11,211,212],{},"地图、演示视频、客服 iframe 经常从 0 高度起步，加载完撑到 400 多像素。改法是外层容器写死比例，iframe 填满容器。",[125,214,218],{"className":215,"code":216,"language":217,"meta":83,"style":83},"language-css shiki shiki-themes github-light github-dark",".embed { aspect-ratio: 16 \u002F 9; width: 100%; }\n.embed iframe { width: 100%; height: 100%; border: 0; }\n","css",[131,219,220,262],{"__ignoreMap":83},[134,221,222,225,228,232,235,238,241,244,247,250,252,255,259],{"class":136,"line":137},[134,223,224],{"class":148},".embed",[134,226,227],{"class":140}," { ",[134,229,231],{"class":230},"sj4cs","aspect-ratio",[134,233,234],{"class":140},": ",[134,236,237],{"class":230},"16",[134,239,240],{"class":140}," \u002F ",[134,242,243],{"class":230},"9",[134,245,246],{"class":140},"; ",[134,248,249],{"class":230},"width",[134,251,234],{"class":140},[134,253,254],{"class":230},"100",[134,256,258],{"class":257},"szBVR","%",[134,260,261],{"class":140},"; }\n",[134,263,264,266,269,271,273,275,277,279,281,284,286,288,290,292,295,297,300],{"class":136,"line":84},[134,265,224],{"class":148},[134,267,268],{"class":144}," iframe",[134,270,227],{"class":140},[134,272,249],{"class":230},[134,274,234],{"class":140},[134,276,254],{"class":230},[134,278,258],{"class":257},[134,280,246],{"class":140},[134,282,283],{"class":230},"height",[134,285,234],{"class":140},[134,287,254],{"class":230},[134,289,258],{"class":257},[134,291,246],{"class":140},[134,293,294],{"class":230},"border",[134,296,234],{"class":140},[134,298,299],{"class":230},"0",[134,301,261],{"class":140},[11,303,304,305,308],{},"这个站的定价页嵌了三个客户评价视频，原来每个都从 0 撑到 320 像素，改完位移归零。顺手把 YouTube 的嵌入换成 ",[131,306,307],{},"youtube-nocookie"," 加懒加载，首屏也轻了一点。",[15,310,311],{"id":311},"骨架屏要预留真实高度",[11,313,314],{},"骨架屏高度和真实内容不一致，等于位移换了个形式。我们的做法是拿一次真实数据截图量出高度，骨架屏写死这个值，误差控制在 8 像素以内。这个站的后台截图区差了 120 像素，改完才真正消掉。",[15,316,317],{"id":317},"广告位和推荐位",[11,319,320],{},"有广告或者合作推荐的站，位子必须提前占好。常见做法是给容器一个 min-height，里面没内容时也占着。这个站的博客文末有一条合作推荐，原来从 0 撑到 180 像素，用户读到最后一行时正文被推走，改完加了 min-height 就好了。",[11,322,323],{},"这类位子的另一个问题是内容有时不来，占位就一直空着。我们一般给个 3 秒超时，超时后容器收起，收起动作放在用户看不见的区域，不影响 CLS。",[15,325,326],{"id":326},"验收方式",[11,328,329],{},"改完别只看 Lighthouse。用 Chrome Performance 面板录一次移动端加载，看 Experience 轨道还有没有位移；再等两周看 GSC 的真实数据。这个站实验室数据第一天就到 0.02，真实数据两周后稳定在 0.09，差距来自长尾页面——旧博客里有 40 多张历史图片还在漏。",[11,331,332],{},"我们给客户定的验收标准是两件事同时满足：实验室三次测试都在 0.1 以下，真实数据两周后 P75 在 0.1 以下。只看前者容易自欺，只看后者周期太长，项目会拖。",[11,334,335],{},"最后提醒一句：公众号文章和富文本编辑器粘进来的图片最容易漏。我们的做法是在编辑器上传环节强制写入宽高，从源头堵住，不然三个月后又会冒出来。",[337,338,339],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":83,"searchDepth":84,"depth":84,"links":341},[342,343,344,345,346],{"id":119,"depth":84,"text":120},{"id":208,"depth":84,"text":209},{"id":311,"depth":84,"text":311},{"id":317,"depth":84,"text":317},{"id":326,"depth":84,"text":326},"技术SEO","2025-11-18","一个开发者工具站 CLS 0.31，不是靠玄学优化的：168 个图片补宽高、6 个 iframe 用 aspect-ratio 占位、骨架屏写死真实高度。附查询方法和两段可直接抄的代码。",{},"\u002Fblog\u002Fcls-image-dimension-fix",{"title":111,"description":349},"blog\u002Fcls-image-dimension-fix",[355,356,357],"CLS","图片尺寸","布局偏移","NtIb0Arzyvtl8vRSevA0gvsTFcRnzCleytBU6Dx3vKk",{"id":360,"title":361,"author":6,"body":362,"canonical":93,"category":347,"cover":93,"date":542,"description":543,"draft":97,"extension":98,"keywords":93,"meta":544,"navigation":100,"noindex":97,"ogImage":93,"path":545,"seo":546,"seoDescription":93,"seoTitle":93,"stem":547,"tags":548,"updated":93,"__hash__":551},"blog\u002Fblog\u002Fgptbot-log-analysis.md","服务器日志里的真 GPTBot：四个识别特征和一次全量统计",{"type":8,"value":363,"toc":534},[364,367,370,381,387,393,399,403,406,409,412,501,504,507,510,513,516,519,522,525,528,531],[11,365,366],{},"光看 user-agent 判断 AI 爬虫，会有大概两成是假的。2025 年 11 月整月，我们统计了四个客户站的日志，AI 爬虫请求合计 4.2 万次，其中自称 GPTBot 的 1.9 万次，核对 IP 之后只剩 1.1 万次是真的。",[15,368,369],{"id":369},"四个识别特征",[11,371,372,376,377,380],{},[373,374,375],"strong",{},"一、user-agent 字符串。"," GPTBot 的完整串是 ",[131,378,379],{},"Mozilla\u002F5.0 AppleWebKit\u002F537.36 (KHTML, like Gecko); compatible; GPTBot\u002F1.2; +https:\u002F\u002Fopenai.com\u002Fgptbot","。注意后面那个说明 URL，正规爬虫都会带。",[11,382,383,386],{},[373,384,385],{},"二、来源 IP。"," OpenAI 公开了爬虫的 IP 段，维护在 openai.com\u002Fgptbot.json 这类文件里。这一段是关键，UA 能伪造，IP 段伪造不了。",[11,388,389,392],{},[373,390,391],{},"三、请求路径分布。"," 真爬虫的路径分布很散，会顺着内链爬。假爬虫常常只打首页、sitemap 和几个热门 URL，因为它在扫。",[11,394,395,398],{},[373,396,397],{},"四、时间分布。"," 真爬虫按队列来，节奏均匀，凌晨也有。假爬虫扎堆在某个小时。",[15,400,402],{"id":401},"怎么核对-ip","怎么核对 IP",[11,404,405],{},"两步。先把日志里的 IP 提出来做反向解析，看 PTR 记录是否落在官方域名下；再拿 IP 去官方公布的段里做匹配。两步都过才算真。",[11,407,408],{},"我们一开始偷懒只做了 UA 过滤，得出\"GPTBot 抓了 1.9 万次\"的结论，还挺高兴。后来做 IP 核对，发现 8000 次的来源是几个云主机 IP，UA 一模一样，路径全在首页。那批是有人在批量采集。",[15,410,411],{"id":411},"一个月的数据",[413,414,415,431],"table",{},[416,417,418],"thead",{},[419,420,421,425,428],"tr",{},[422,423,424],"th",{},"爬虫",[422,426,427],{},"声称次数",[422,429,430],{},"核实后",[432,433,434,446,457,468,479,490],"tbody",{},[419,435,436,440,443],{},[437,438,439],"td",{},"GPTBot",[437,441,442],{},"19000",[437,444,445],{},"11000",[419,447,448,451,454],{},[437,449,450],{},"OAI-SearchBot",[437,452,453],{},"4100",[437,455,456],{},"3400",[419,458,459,462,465],{},[437,460,461],{},"ChatGPT-User",[437,463,464],{},"1200",[437,466,467],{},"900",[419,469,470,473,476],{},[437,471,472],{},"PerplexityBot",[437,474,475],{},"2300",[437,477,478],{},"1900",[419,480,481,484,487],{},[437,482,483],{},"ClaudeBot",[437,485,486],{},"3200",[437,488,489],{},"2800",[419,491,492,495,498],{},[437,493,494],{},"Bytespider",[437,496,497],{},"17000",[437,499,500],{},"16000",[11,502,503],{},"Bytespider 是字节的爬虫，量大是正常的。OAI-SearchBot 值得单独说：它负责给 ChatGPT 搜索抓内容，抓得比 GPTBot 频繁，路径也更集中在对比页和文档页。",[15,505,506],{"id":506},"这个统计能干什么",[11,508,509],{},"第一，判断你的文档有没有人在读。如果一个站 GPTBot 三个月没来，不是它屏蔽你，是你没内链、没 sitemap、或者全站都在 robots 里挡着。",[11,511,512],{},"第二，看它抓了什么。OAI-SearchBot 如果反复抓你的定价页和对比页，说明你的对比类内容进了它的候选池，这时候把这两页做得更可引用，收益最直接。",[11,514,515],{},"第三，发现抓取异常。有个客户站 11 月中旬 GPTBot 访问量突然掉 90%，查出来是他们上了 CDN 的防爬规则，把 AI 爬虫一起挡了。这种事故不看日志永远发现不了。",[15,517,518],{"id":518},"怎么把这件事做成常态",[11,520,521],{},"我们现在给客户的建议是每月跑一次，写成一个固定脚本，输出三行字：本月 AI 爬虫总请求、核实后占比、抓取最多的五个路径。三行字放在月报第一页，比任何流量曲线都直观。",[11,523,524],{},"有个客户靠这三行字发现了另一件事：他们的文档站被 OAI-SearchBot 抓得很勤，但博客基本没人碰。原因是博客全是\"行业趋势\"这类内容，没有能被直接搬走的答案。他们后来把博客砍掉一半，人挪去做文档，两个月后文档的引用进了 AI 回答。",[11,526,527],{},"日志不会告诉你该写什么，但它会告诉你什么没被读。后者更有用。",[15,529,530],{"id":530},"一句提醒",[11,532,533],{},"别为了好看去改 UA 统计口径。我们见过代理商把 Bytespider 全算成\"AI 搜索流量\"，数字翻了三倍。跟老板汇报前，先问一句这批 IP 核实过没有。",{"title":83,"searchDepth":84,"depth":84,"links":535},[536,537,538,539,540,541],{"id":369,"depth":84,"text":369},{"id":401,"depth":84,"text":402},{"id":411,"depth":84,"text":411},{"id":506,"depth":84,"text":506},{"id":518,"depth":84,"text":518},{"id":530,"depth":84,"text":530},"2025-11-20","2025 年 11 月一个月，四个站共有 4.2 万次 AI 爬虫请求，冒充 GPTBot 的占了 9000 次。四个特征能分辨真假，光看 user-agent 会被骗。",{},"\u002Fblog\u002Fgptbot-log-analysis",{"title":361,"description":543},"blog\u002Fgptbot-log-analysis",[439,549,550,347],"AI爬虫","日志分析","Gdg0-E4uIHGlku3NNATeUfLNo0XBKOhBEq2iwm1_Uck",1794088110724]