SERP 结果里的三个 URL:link、url、source_url 到底该用哪个

采集搜索结果时,很多人直接拿 link 存库。三个月后会发现三个问题:同一个页面出现多行、统计里混进了 google.com、域名分布对不上。根因不是采集,是没分清响应里几个 URL 字段的语义。

这篇把字段拆开,给一套可落地的规范化方案。

字段语义

SerpBase 的网页搜索结果里,与 URL 相关的字段有四个(均为可选,按解析情况返回):

字段 含义 用途
link 解析器返回的主链接 通常直接可用
url 规范化后的目标 URL 一般与 link 相同
source_url 仅当观察到 Google 跳转/来源 URL 时返回 溯源、调试,不是目标地址
display_url / display_link 展示用域名或文本 展示,不可用于去重

另外,自然结果里可能有 sitelinks 数组,每条也带 link、url、source_url——站内链接不能混进主结果统计,否则一个页面会被算成五条。

三个现实问题:

一、跳转链。 Google 有时返回 google.com/url?sa=t&url=... 形态的链接。这类地址放在 source_url 里,若拿它当目标地址,统计会全部算到 google.com 头上。

二、同一页面的多种写法。 http 与 https、带不带 www、尾斜杠有无、utm_* 跟踪参数——不同关键词下可能各出现一次,直接存就是重复行。

三、别名与规范化差异。 link 和 url 大多数时候相同,但不保证永远相同;去重应该基于规范化结果,而不是原始字符串。

规范化函数

from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit

TRACKING = {
    "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content",
    "gclid", "fbclid", "ref", "source",
}

def canonical_url(raw: str) -> str:
    parts = urlsplit(raw.strip())
    host = parts.netloc.lower()
    if host.startswith("www."):
        host = host[4:]
    query = [(k, v) for k, v in parse_qsl(parts.query, keep_blank_values=True)
             if k.lower() not in TRACKING]
    path = parts.path.rstrip("/") or "/"
    return urlunsplit(("https", host, path, urlencode(query), ""))

规则按需调整,但方向固定:统一 scheme、去 www、去尾斜杠、去跟踪参数、丢 fragment。查询参数不要一刀切删——有些页面靠 ?id= 区分内容,删了就合并错了。

存储与去重

row = {
    "keyword": kw,
    "rank": item.get("rank"),
    "canonical": canonical_url(item.get("url") or item["link"]),
    "raw_link": item["link"],
    "source_url": item.get("source_url"),      # 保留,做溯源
    "display_url": item.get("display_url"),
    "is_sitelink": False,
}

三个原则:

  • 唯一键用 canonical + keyword,不用原始 link
  • 原始字段全部保留,规范化只是新增一列,不覆盖原文
  • source_url 单独存,它证明「这条结果来自哪次 Google 跳转」,是排障和审计的凭据

统计时的口径

  • 独立域名数:按 canonical 的 host 去重,不要用 display_url(它可能带省略号)
  • 首次出现:按 canonical 去重后取最小 rank
  • 新老页面对比:同一个 canonical 跨时间比较,而不是比较两次的原始 link

五个坑

坑 1:用 source_url 当目标地址。 统计全跑到 google.com,域名分析直接失真。

坑 2:用 display_url 做去重。 它是展示文本,可能被截断,也不是唯一标识。

坑 3:把 sitelinks 混进主结果。 一个页面变成多条,排名分布全错。

坑 4:无脑删所有查询参数。 有些页面靠参数区分内容,删了就误合并。

坑 5:不保留原始字段。 规范化规则一旦调整,没有原文就无法回溯,只能重新采集(又花 credits)。

小结

URL 处理的链路:认字段(link/url/source_url/display_url)→ 规范化(scheme/host/path/query)→ 用 canonical 去重 → 原始字段留档。这套东西不复杂,但它是搜索数据质量的地基——地基歪了,后面的排名、域名、竞品分析全是错的。

字段的可空性与语义以 SerpBase 文档 为准,source_url 只在观察到跳转时返回。你们的 SERP 数据是怎么去重的?评论区聊聊。

posted @ 2026-10-26 08:58  蜘蛛人  阅读(4)  评论(0)    收藏  举报