SEO

5 万 URL 的 Screaming Frog 抓取,用 Claude Code 做分析:4 小时产出一份可执行的修复清单

5 万 URL 的 Screaming Frog 抓取,用 Claude Code 做分析:4 小时产出一份可执行的修复清单
目录

抓取在一个星期二的凌晨 1 点左右跑完。50,247 个 URL。Internal 标签页里堆满了 noindex 标签,重定向链在 2018 年那次没人记得的 URL 改版后堆到了 4 层,2016 年的一个 /blog/ 目录还在被反复抓取。上一个代理商告诉客户,网站"基本没问题,只是需要更多内容"。我坐在那儿盯着 Issues 标签页上 14,000 个孤立页面,看了 10 分钟,意识到一周内没人能人工分诊完。

所以我不再自己分诊。我把所有需要用到的标签页全部导出,打开 Claude Code,让它去做我本来要用很长时间、而且做得不好的事:把 5 万行抓取噪音转化成开发周五能直接动手的、按优先级排好序的修复清单。

下面就是完整的工作流。可复现,端到端大概 4 小时,输出一个 Markdown 文件,工程团队下周一就能拆成 Jira 工单。

为什么不能直接用 Screaming Frog 的 UI 界面

如果你的网站只有 500 个 URL,答案很简单:用 UI 就行。过滤 Issues 标签页,扫一眼警告,修掉明显的问题,完事。

到了 5 万 URL 这个规模,UI 反而是反作用。你可以过滤 "Orphan Pages" 然后盯着 14,000 行。你可以按字数排序看到 9,000 个低质页面。你可以按重定向跳数排序看到五层深的链。所有信息都在,但"一边脑子里装着 5 万行数据、一边人工分诊"的认知负担,就是大站审计要花两周的根本原因。大部分代理商的解决方案是:按两周"审计时间"收费,交付一份 200 页的 PDF。PDF 永远躺在 Google Drive 某个文件夹里,什么也不会改变。

替代方案是:把抓取当作数据,而不是报告。导出标签页。用脚本跑这些导出。强制让分析明确说明它把什么当作问题、什么不算。输出是一份列表,不是 PDF,而且列表按影响力排序。

第 1 步:按你真正想回答的问题去配置抓取

在点 "Start" 之前,先关掉会污染导出的选项。Screaming Frog 能扫的 300+ 个"问题"里,大多数跟一份按优先级排的修复清单无关。

5 万 URL 站点需要关心的抓取设置:

  • Crawl Limit(抓取上限):设到 50,000 以上。默认的 500 完全不够。
  • Crawl subdomains(抓取子域):如果 www、cdn.、blog. 属于同一资产,勾上。
  • Check Images / CSS / JS(检查图片/CSS/JS):第一遍关掉。你不是在跑 Core Web Vitals 审计。你在找结构性问题。性能那一轮后面再开。
  • Crawl Linked XML Sitemaps(抓取关联的 XML 站点地图):开。这是唯一能找到"Google 知道存在、但站内没链接"的 URL 的方法——也就是真正的孤立页面列表。
  • Respect robots.txt(遵守 robots.txt):先关掉。你想看到被屏蔽的内容,而不是假装它不存在。
  • Render(渲染):第一遍关掉 JS 渲染。它会让抓取时间变成三倍。内容质量那一轮再用 JS 渲染跑一次。

开跑。5 万 URL 的站点通常要 30-90 分钟,看服务器响应速度。喝杯咖啡去。v23 及以上版本会自动把抓取结果存到数据库文件,你不用手动"保存"。

第 2 步:把所有需要的标签页导出为 CSV

这是大部分人会跳过的环节。他们只导出 Internal 标签页就当完事了。你需要跨标签页的数据才能真正发现关键词蚕食和孤立页面簇。

在 Bulk Export 菜单里(顶部菜单,不是单个标签页的 Export 按钮),勾选这些:

  • Internal: All — 主列表,包含状态码、title、H1、H2、字数、站内入链/出链、可读性。
  • Internal: HTML — 同上,只过滤 HTML(去掉图片、CSS、JS)。
  • Response Codes: Redirection (3xx) — 所有重定向 URL,带重定向目标和链长度。
  • Response Codes: Client Error (4xx) — 所有 404 和 4xx。
  • Page Titles: Missing / Duplicate / Over 60 Characters — 三个独立导出。
  • Meta Description: Missing / Duplicate / Over 155 Characters — 又是三个。
  • H1: Missing / Duplicate / Multiple — 再三个。
  • H2: Missing — 一个。
  • Content: Thin (under 200 words) — 一个。
  • Inlinks: All Inlinks to URLs with 4xx Response — 告诉你哪些页面在链向死链,而不只是死链本身存在。
  • Inlinks: All Inlinks to URLs with 3xx Redirection — 重定向同理。
  • Orphan URLs(在 Reports > Export 下,或者把 Internal 标签页过滤成 "No Inlinks" 然后导出)——这就是你的孤立页面列表。
  • Sitemap URLs(在 Reports > Sitemaps 下)——你在 XML 里声明的、Google 知道的所有 URL。

总共大约 15 个 CSV。全部放进一个叫 crawl-export-2025-08-14/ 的文件夹。文件名带日期后缀,这样下次抓取不会覆盖。现在你有了原料。

第 3 步:把文件夹交给 Claude Code

打开终端,cd 到导出文件夹的上一层,启动 Claude Code。告诉它文件结构和目标。

一个可用的 prompt:

我有一个 5 万 URL 的电商站点的 Screaming Frog 抓取,导出在 crawl-export-2025-08-14/。CSV 文件包括:internal_all.csvinternal_html.csvredirects_3xx.csverrors_4xx.csvtitles_*.csvmeta_*.csvh1_*.csvthin_content.csvinlinks_4xx.csvinlinks_3xx.csvorphan_urls.csvsitemap_urls.csv

我要你写 Python 脚本(用 pandas),产出一个统一的、按优先级排序的修复清单,五个部分:(1) 值得挽回 vs 值得下架的孤立页面,(2) 要拉平的重定向链,(3) 要合并或删除的低质内容,(4) 两个或以上页面抢同一主关键词的关键词蚕食簇,(5) 页面级别的卫生问题(title、meta、H1 缺失或重复)。每条发现要有 URL、原因、建议动作、1-5 的优先级分数(1 最高,5 最低)。最后输出一个 fix-list.md 文件。

Claude Code 会搭脚本的脚手架、跑它们、发现边界情况时迭代。终端里会先看到一个 plan,然后是一连串 python3 analysis_orphans.py 这样的执行。第一轮不要打断。让它把发现都摆出来,然后你用人的视角过一遍,再提反馈。

第 4 步:真正重要的四个桶

5 万 URL 的审计有一堆问题,大多数并不重要。下面的分桶逻辑是我用的,按优先级排序。

桶 1:有流量潜力的孤立页面

孤立页面不是一个统一的问题。孤立页面指的是"站点上存在、返回 200、但没有任何内链指向它"的页面。这里面有 2014 年 WordPress 自动生成的 14,000 个 tag 页面,也包括一篇 4,000 字的支柱文章——它只在 2019 年某封 newsletter 邮件里被链过一次,然后就被遗忘了。

脚本需要三个信号:(a) URL 是不是在孤立列表里,(b) URL 是不是在 sitemap 里,(c) URL 有没有外链(单独加载一份 Ahrefs/Semrush 导出)。输出是两类:

  • 值得挽回——孤立页面 + 至少一个外链,或在 sitemap 中,或近 90 天有非零的 GSC(Google Search Console, 谷歌搜索控制台)曝光。这些是 Google 在推流量过来、但用户从站内导航找不到的页面。30 天内要补内链。
  • 值得清理——没有外链、不在 sitemap 里、零 GSC 流量。这是纯死重。加 noindex 或 410 掉。

一次典型的 5 万 URL 审计,挽回列表 50-200 条,清理列表几千条。别听人说"先留着"——它们在消耗抓取预算(crawl budget, Googlebot 在一定时间内愿意抓取你网站的总页数)。

桶 2:重定向链

3 层及以上的重定向链是真问题。浏览器发出请求,服务器返回 301,浏览器跟到下一个 URL,再拿到一个 301,再跟一次,才拿到 200。每跳一个 100-300 毫秒往返。移动端一个 5 跳链能加 1.5 秒延迟。Googlebot 跟 5 跳就放弃——所以经过 5 跳链传递的任何权重到第 5 跳就死了。

脚本读 redirects_3xx.csvinlinks_3xx.csv,按 source URL 关联起来,识别链。对每条链,找到最终目标并报告每跳的入链数。修复清单长这样:"链:/old/2018/sale → /new/sale → /sale/2024 → /promo → /promo/summer。1,847 条入链指向 /old/2018/sale。把全部 1,847 条入链更新为直接指向 /promo/summer,删除中间跳。"

1,847 这个数字就是为什么这事重要。4 跳链 1,800 入链 = 一个 Jira 工单解决 7,200 次冗余请求。这种修复是开发最喜欢的——因为能量化。

桶 3:低质内容

Screaming Frog 默认的"低质"过滤(200 字以下)偏保守。多数 5 万 URL 的电商站,真正的低质阈值要更高——类目页 300 字以下,博客 500 字以下。脚本把 thin_content.csv 跟站内入链数、GSC 曝光关联起来,然后按页面类型套阈值(用 URL 模式判断:/product//category//blog//tag//author/)。

输出三类标记:

  • 高曝光低质页——500 字以下,但月 GSC 曝光 1,000+。Google 在把流量送给一个接不住的页面。要么扩到 1,200+ 字,要么合并到更强的页面并 301。
  • 零曝光低质页——300 字以下,GSC 曝光 0,外链 0。纯浪费。noindex、410 或直接删。
  • 模板化低质页——一批共享同一模板特征的低质页(比如 200 个 /tag/[城市] 页面,本地 SEO 那一波玩剩下的)。合并到一个动态页,或者整个删掉。

桶 4:关键词蚕食

四个桶里这个最微妙。蚕食不一定是问题——有时候两页抢同一个关键词都能拿到流量。真正的信号是:两页都瞄准同一个主关键词,一个排前 3,另一个排 8-20,而且每次 Google 重抓它们就换位。这是一场内耗,两页都亏。

脚本看不到 GSC 的位置数据,除非你喂给它。把 GSC 的 "Pages" 报告按这次抓取里的 URL 过滤导出,再导出 "Queries" 报告,按 URL 关联起来。脚本按主关键词给页面分簇(从页面 title 里抽主关键词——这个函数 Claude 会写,通常用个简单的 TF-IDF(Term Frequency–Inverse Document Frequency, 词频-逆文档频率)或 YAKE 风格的方法),然后标记出 2+ 页面且同一关键词是双方 top GSC query 的簇。

修复清单会列:哪个簇、应该胜出的页面(通常入链更多、内容更多、发布更早的那个),以及应该被合并的页面(301 到胜出页)或需要被差异化的页面(改写成瞄准不同搜索意图)。

第 5 步:评分系统

没有评分系统的话,"5 个入链的高曝光低质页"会和"1,800 入链的 4 跳重定向链"拿同样的注意力。开发从上往下过列表,根本到不了那个 1,800 入链的链。

评分是简单的 1-5,带显式权重:

分数 含义 行动时间
1 紧急:1,000+ 入链,或 5 跳链,或 4xx 页面有 10K+ 月曝光 本迭代
2 高:200-1,000 入链,或 3 跳链,或低质页 1K-10K 曝光 本迭代
3 中:50-200 入链,或 2 跳链,或有明显赢家的蚕食 下迭代
4 低:50 入链以下,单跳重定向,或蚕食双方都不明显 积压
5 琐碎:卫生问题(meta description 缺失之类) 有空再说

分数由脚本算,不是人。这样可复现——60 天后再跑一次审计,同一问题得分一模一样。

第 6 步:输出

输出是一个 fix-list.md,一个桶一节,按分数排序、再按入链数排序。每条发现长这样:

### [Score 1] 重定向链:/old/2018/sale/ → /sale → /sale/2024 → /promo/summer
- 第一跳入链:1,847
- 最终目标:/promo/summer
- 建议动作:把全部 1,847 条入链更新为直接指向 /promo/summer,删除中间 301
- 负责人:Web 团队(1 个 Jira 工单)
- 预计抓取预算回收:~7,200 次/月冗余请求

这就是工程团队拿来干活的成品。不要 PDF。不要"审计发现汇报"。就一个 Markdown,带按优先级排好的工单,每条都有 URL、原因、建议动作、负责人猜测、可量化的结果。

Claude Code 第一遍跑错的地方

按上面那套 prompt 第一次跑出来的脚本,犯过三个值得知道的问题。

第一,Ahrefs 导出只给了有外链的 URL,而它用的是 left-join 而不是 left-anti-join,导致所有孤立页面都被当成"值得挽回"。2,000 个零外链的页面被算进来,仅仅因为它们出现在另一张表里。永远要写显式的 join 逻辑,然后验证一下基数对不对。

第二,它没处理重定向目标列里的 URL 编码字符。/category/women%27s-shoes 这种目标被拿来跟 /category/womens-shoes 匹配,被算成坏链。修法是在脚本里加一个 .str.replace('%27', "'").str.lower() 的归一化步骤,但你得想到要这么写。

第三,它只用字数当作低质信号,把几百个本来就该短的落地页(黑五大促页、联系页)也标成低质。修法是加一个 URL 模式白名单:URL 匹配 /sale//contact//shipping//returns/ 的,跳过低质标记。

这些都不是 deal-breaker。多花 30 分钟第二遍就能补上。但这就是"周三把分析交给客户"和"周五才交"的差别。

真正要学到的东西

我反复看到的大站 SEO 审计的错,不是分析师漏掉了重定向链或孤立页面。Screaming Frog 的 UI 都能看见。错在分析停在"这里有 50,000 个问题",永远到不了"这里有 12 个本迭代要修的东西"。代理商交一份 200 页 PDF,客户点点头,六个月里什么也不变。

Claude Code 工作流没让分析变聪明,它让分析做完。它把 5 万行的抓取结果过四个桶、一套评分规则、一个 Markdown。真正的 SEO 判断——什么算低质、什么算蚕食、什么值 1 分——还是在分析师脑子里。Claude Code 只是把人手工排 14,000 行那部分省掉,把本该花掉的那 4 小时还给你。

你要是给 5 万 URL 的站点做审计但没有这套工作流,审计得花两周。有了这套,4 小时就完事,而且交付的东西开发团队真的能用。区别就在这儿。