谷歌SEO 内链地图脚本:Python 画出权重分发,揪出孤岛页

谷歌SEO 内链地图脚本:Python 画出权重分发,揪出孤岛页

内链是独立站最容易"做了但没做对"的环节。本篇给一个可运行的内链拓扑分析脚本:抓取页面间的链接关系,输出孤岛页、权重黑洞、深链页三类问题清单,帮你把权重分发画成一张可执行的地图。官方规范见搜索中心内链文档。

一、先说明:内链分析为什么要"脚本化"

手动看内链只能看到"有没有",看不到"分布合不合理"。三个典型问题必须靠数据发现:

问题 表现 后果
孤岛页 没有任何页面向它链接 权重无法流入,难以收录
权重黑洞 大量页面链向同一低价值页 权重被吸走,核心页分不到
深链页 需要 5+ 次点击才能到达 爬虫难到达,收录延迟

脚本思路:抓取站内页面 → 提取页面里的站内链接 → 构建"谁指向谁"的关系 → 统计入链数、出链数、最深路径。

二、脚本准备

  • urls.txt:每行一个站内 URL(从 sitemap 导出全量)。
  • Python 3.8+,仅标准库(urllib + re + collections)。
  • 只抓本站域名,避免外链干扰。

三、内链地图脚本

python 复制代码
import re
import urllib.request
import urllib.error
from urllib.parse import urlparse
from collections import defaultdict

DOMAIN = "example.com"  # 换成你的域名
START_URLS = [u.strip() for u in open("urls.txt", encoding="utf-8") if u.strip()]

def fetch(url):
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            return resp.read().decode("utf-8", "ignore")
    except Exception:
        return ""

def extract_internal_links(html, page_url):
    links = set()
    for m in re.finditer(r'href=["\']([^"\']+)["\']', html, re.I):
        href = m.group(1).strip()
        if href.startswith("#") or href.startswith("mailto:") or href.startswith("javascript:"):
            continue
        if href.startswith("/"):
            href = f"https://{DOMAIN}{href}"
        elif href.startswith("http"):
            parsed = urlparse(href)
            if parsed.netloc != DOMAIN:
                continue  # 外链跳过
        else:
            continue
        links.add(href.split("#")[0].split("?")[0])
    return links

# 构建关系
incoming = defaultdict(set)   # 目标页 -> 来源页集合
outgoing = defaultdict(set)   # 来源页 -> 目标页集合
pages = set(START_URLS)

for page in START_URLS:
    html = fetch(page)
    targets = extract_internal_links(html, page)
    pages.update(targets)
    for t in targets:
        incoming[t].add(page)
        outgoing[page].add(t)

print(f"抓取页面数: {len(START_URLS)}  发现站内链接目标: {len(pages)}")

# 1. 孤岛页:没有入链
orphans = [p for p in pages if len(incoming.get(p, set())) == 0 and p not in START_URLS]
print(f"\n=== 孤岛页(无入链,{len(orphans)})===")
for p in orphans[:15]:
    print(f"  {p[:90]}")

# 2. 权重黑洞:入链多但页面价值低(这里用入链数>10 且 出链数==0 近似)
print(f"\n=== 权重黑洞候选(入链多且无出链,{len(pages)} 页中)===")
for p, srcs in incoming.items():
    if len(srcs) >= 10 and len(outgoing.get(p, set())) == 0:
        print(f"  入链{len(srcs)}个  {p[:90]}")

# 3. 入链排名:核心页是否获得足够权重
print(f"\n=== 入链 Top 15 ===")
for p, srcs in sorted(incoming.items(), key=lambda x: -len(x[1]))[:15]:
    print(f"  入链{len(srcs):>3}个  {p[:80]}")

四、输出解读与动作

输出 判定 动作
孤岛页 无入链 = 权重进不去 从相关核心页加 1-2 条自然链接
权重黑洞 入链多但本身无价值 给黑洞页加 nofollow 或减少指向它的链接
入链 Top 核心页应排在前列 Top 页不是核心页时,调整内链布局

硬决策规则:核心转化页/核心内容页的入链数应该排在全站前 20%;孤岛页超过全站 10%,说明导航结构有问题,先改导航再补单向链接。

五、常见坑

坑 后果 正解
只抓首页开始 漏掉深链页面 从 sitemap 导全量 URL
把外链算进内链 关系图失真 只保留本站域名
只看数量不看路径 深链页被忽略 结合导航层级判断
改完不复查 内链又乱 每月重跑对比

六、FAQ

Q1:脚本能处理动态页面吗?

能抓静态 HTML;JS 渲染页面(SPA)需要预渲染或浏览器工具,脚本结果只作参考。

Q2:入链多少算健康?

没有固定数字,看结构:核心页 > 分类页 > 文章页 > 分页页。重点看相对分布,不看绝对值。

Q3:孤岛页一定要处理吗?

看价值:高价值内容页必须处理;低价值索引垃圾页建议 noindex 或删除,别为链接而链接。

七、行动清单

  1. 从 sitemap 导出全量 URL 生成 urls.txt,跑内链地图脚本。
  2. 处理孤岛页:核心内容补入链,垃圾页清理。
  3. 检查权重黑洞:低价值高入链页收敛权重。
  4. 每月重跑一次,对比入链分布变化。
  5. 配合官方内链最佳实践文档逐项核对。

完整版内链地图脚本(含深链层级计算、导航结构分析、可视化输出)我整理成了 PDF,评论区扣「内链」或私信我,免费发你。也欢迎一起交流谷歌SEO实战问题。

相关推荐
bro_Java6661 小时前
《排序的底层逻辑:比较、交换与分治》
java·算法·排序算法
AI源码1 小时前
基于 Python 的汽车市场数据分析与可视化平台
python·数据分析·汽车
会飞锦鲤1 小时前
基于 SVM + HOG 的铸造缺陷检测系统
python·opencv·机器学习·计算机视觉·缺陷检测·图像分类·svm
炫酷的大高个2 小时前
6 亿播放的闪身步,我用前端算出 15 倍重心差
前端·javascript
不可能片场2 小时前
内容运营自动化 配图折行别把词切两半
前端·electron
starrysky8102 小时前
zipfile 中文乱码修复:把已知 GBK 旧 ZIP 解压到正确中文目录
python
Lank_M2 小时前
HEIC转JPG统一转sRGB,P3高饱和色就回不来了
前端
补码缩写2 小时前
sharp默认转JPG颜色没错,ICC和EXIF却全没了
前端
用户7783366132112 小时前
SerpBase AI Overview 引用卡片:React 组件实战
前端
林小帅2 小时前
【笔记】Prisma v7 + SQLite TS2305 及连锁 TS7006 问题
前端·javascript·后端