Parry

SEO 自动巡检怎么做:用 PageSpeed、DNS、SSL 与 WHOIS 定位网站问题

  •  
  •   Parry ·
    PRO
    · 7h 52m ago · 73 views

    SEO 巡检不能只看一个分数。页面加载变慢、Canonical 配置错误、DNS 记录漂移、证书临近到期,都会影响搜索引擎访问和用户体验,但它们属于完全不同的问题域。如果把所有信号混成一个“站点健康分”,报告看起来完整,却很难指导修复。

    更实用的做法,是把巡检拆成三层:

    1. URL 层检查页面性能与 SEO 审计结果;
    2. 域名层检查 DNS 、SSL 与 WHOIS ;
    3. 规则层结合历史基线、数据新鲜度和连续次数生成行动项。

    本文使用 网页性能与 SEO 评分DNS 查询SSL 证书解析WHOIS 查询,搭建一条可定时执行、可追踪、不过度告警的网站巡检管线。

    网页性能与 SEO 评分

    一张图看懂巡检数据怎么流动

    同一个站点可以有几十个重点 URL ,但通常只对应一个主域名。页面评分应按 URL 执行,DNS 、SSL 、WHOIS 则应按域名去重执行,最后再汇聚成报告。

    网站巡检信号汇聚流程

    这条数据流有两个关键边界:页面结果不能代替域名状态,域名异常也不能直接伪装成页面 SEO 评分失败。两类检查分别保留原始状态,规则层只负责解释和分级。

    四个接口分别回答什么问题

    检查范围 接口 主要结果 适合回答的问题
    URL PageSpeed 四类评分、FCP 、LCP 、TBT 、CLS 、SEO 审计、TopIssues 页面是否变慢,标题、Canonical 、robots.txt 、viewport 是否存在明显问题
    域名 DNS A 、AAAA 、CNAME 、MX 、TXT 、NS 、SOA 等记录 解析记录是否符合预期,是否发生未经确认的变化
    域名 SSL 证书链、有效期、主机与诊断信息 证书是否有效,是否接近到期,主机名是否匹配
    域名 WHOIS 注册时间、到期时间、注册商、名称服务器等 域名注册信息是否可用,重要日期是否需要提醒

    WHOIS 字段可能受注册局和隐私保护影响。字段缺失应标记为“未知”,不能直接判定为域名故障。

    第一步:规范化 URL 和域名

    巡检任务的输入不是一个模糊的“站点”,而是两组明确目标:

    • URL 清单:首页、产品页、文档页、转化页等重点页面;
    • 域名清单:从 URL 中提取并标准化后的唯一域名。
    from urllib.parse import urlsplit
    
    
    def normalize_target(page_url: str) -> tuple[str, str]:
        parsed = urlsplit(page_url)
        if parsed.scheme not in {"http", "https"} or not parsed.hostname:
            raise ValueError("A valid HTTP or HTTPS URL is required")
    
        hostname = parsed.hostname.encode("idna").decode("ascii")
        normalized_url = parsed._replace(fragment="").geturl()
        return normalized_url, hostname
    

    不要用字符串切割域名。真实 URL 可能包含端口、国际化域名、IPv6 或路径中的相似文本。

    第二步:采集页面性能和 SEO 信号

    PageSpeed 接口当前使用 GET /websitetools/pagespeed-score,支持 mobiledesktop 两种策略,默认是 mobile。一次请求可以返回:

    • Performance 、Accessibility 、Best Practices 、SEO 四类评分;
    • FCP 、LCP 、Speed Index 、TBT 、CLS 等页面体验指标;
    • 标题、描述、Canonical 、HTTP 状态、robots.txt 、viewport 等 SEO 审计摘要;
    • 最多 10 条主要待优化项;
    • 报告生成时间、报告版本和缓存标记。

    新接入建议把 AppKey 保存在服务端环境变量中,并通过 Header 传递:

    import json
    import os
    from urllib.parse import urlencode
    from urllib.request import Request, urlopen
    
    
    def fetch_pagespeed(page_url: str) -> dict:
        query = urlencode({
            "url": page_url,
            "strategy": "mobile",
            "locale": "zh-CN",
            "categories": "performance,accessibility,best-practices,seo",
            "forceRefresh": "false",
        })
        request = Request(
            f"https://api.gugudata.com/websitetools/pagespeed-score?{query}",
            headers={"X-GUGUDATA-APPKEY": os.environ["GUGUDATA_APPKEY"]},
            method="GET",
        )
        with urlopen(request, timeout=60) as response:
            payload = json.load(response)
    
        data_status = payload.get("DataStatus", {})
        if int(data_status.get("StatusCode", 0)) != 100:
            message = data_status.get("StatusDescription", "PageSpeed failed")
            raise RuntimeError(message)
        return payload.get("Data", {})
    

    HTTP 200 只说明请求得到响应,不能替代业务状态判断。生产实现还要捕获超时和非 2xx 状态,并限制响应体大小。

    第三步:按域名执行 DNS 、SSL 和 WHOIS 检查

    三个域名接口当前都是 GET 请求:

    /v2/websitetools/dns-lookup
    /v2/websitetools/sslcertinfo
    /v2/websitetools/whois
    

    它们与 PageSpeed 存在一个容易踩坑的契约差异:

    接口类型 状态对象 当前成功值
    PageSpeed DataStatus.StatusCode 100
    DNS 、SSL 、WHOIS v2 dataStatus.statusCode 200

    因此,不能把 PageSpeed 的校验器直接复制给 v2 域名接口:

    def require_v2_success(payload: dict) -> dict:
        data_status = payload.get("dataStatus", {})
        if int(data_status.get("statusCode", 0)) != 200:
            message = data_status.get("statusDescription", "Domain check failed")
            raise RuntimeError(message)
        return payload.get("data", {})
    

    聚合层可以把两类结果统一映射为 successfailedunknown,但必须同时保留原始状态字段和采集时间,避免统一过程中丢失排错依据。

    分数下降不等于立刻告警

    巡检系统最难的部分不是请求接口,而是决定哪些信号需要立即处理。建议先识别可用性或安全硬故障,再排除缓存过期和计划内变更,最后比较历史基线。

    SEO 巡检异常分级决策

    这套决策逻辑把结果分为三类:

    • 立即处理:页面不可访问、证书无效等确定性硬故障;
    • 生成行动项:问题偏离历史基线,并连续出现或影响关键页面;
    • 继续观察:单次轻微波动、数据过旧或仍需下一轮确认的信号。

    固定分数线通常不适合所有站点。更可靠的比较条件是同一 URL 、相同检测策略、相近采集条件下的历史变化。

    四类信号如何转换成行动项

    原始信号 容易产生的误判 建议动作
    Performance 或 SEO 分数下降 页面已经故障 查看 TopIssues 、最终 URL 、缓存标记,并与同策略基线比较
    DNS 记录变化 解析一定错误 与预期记录和计划变更窗口核对
    SSL 证书接近到期 网站已经不可访问 生成到期提醒,核对自动续期状态和证书链
    WHOIS 字段为空 域名异常 标记数据缺口,考虑隐私保护与注册局差异

    行动项至少应包含目标、问题类型、严重度、首次发现时间、连续次数、证据摘要、负责人和下一步。没有明确责任人与动作的问题,只是一条日志。

    缓存和数据时间必须可见

    PageSpeed 返回 CachedFetchTime。如果报告只展示“任务在 10:00 执行”,读者可能误以为所有页面都在 10:00 重新检测。

    建议分别保存:

    • scheduled_at:任务计划执行时间;
    • collected_at:本次响应时间;
    • fetch_time:评分报告实际生成时间;
    • cached:是否复用了近期结果;
    • strategy:mobile 或 desktop ;
    • report_version:报告版本。

    常规巡检不应默认对全部页面使用 forceRefresh=true。关键页面出现异常时,可以由受控复核任务请求刷新。本文没有验证具体缓存窗口和刷新成本,因此不提供固定刷新间隔。

    允许“部分完成”,不要用总状态覆盖事实

    PageSpeed 可能成功,而 WHOIS 因字段不可用只返回部分信息; DNS 查询也可能失败,但页面仍然能够访问。一轮巡检最好支持以下状态:

    状态 含义
    complete 计划内检查均得到可用结果
    partial 至少一项成功,至少一项失败或未知
    failed 没有获得可用检查结果
    stale 只有超过时效要求的历史结果

    报告必须展示每个子检查的独立状态。新的临时失败也不应覆盖上一轮仍在有效期内的成功结果。

    一份可执行的巡检报告应该包含什么

    建议按以下顺序组织报告:

    1. 本轮范围:URL 数量、域名数量、检测策略与实际数据时间;
    2. 立即处理:可用性、证书和关键页面硬故障;
    3. 持续问题:连续出现的评分、Canonical 、DNS 或注册信息问题;
    4. 数据缺口:失败、未知、缓存过旧和权限不足;
    5. 行动清单:负责人、优先级、证据和下一次复核时间。

    不要把完整 WHOIS 响应无差别复制到普通报告。它可能包含联系信息,应只保留支持业务判断的必要摘要,并按权限控制原始响应。

    常见问题

    是否需要每天强制刷新全站所有页面?

    通常不需要。先按页面价值分层,常规任务记录缓存状态和真实数据时间;关键页面异常时再进行受控刷新。

    DNS 、SSL 或 WHOIS 失败,是否代表页面 SEO 失败?

    不代表。它们属于域名层信号。报告可以提升其优先级,但不能伪造 PageSpeed 结果。

    单次 PageSpeed 分数下降是否应该告警?

    硬故障可以即时处理;普通波动更适合结合历史基线、连续次数、变化幅度和页面重要性判断。

    同一域名下有很多页面,域名接口需要重复调用吗?

    通常不需要。页面检查按 URL 执行,DNS 、SSL 、WHOIS 按标准化域名去重执行,再在报告阶段关联。

    上线前检查清单

    • URL 任务和域名任务分别去重、缓存和重试;
    • PageSpeed 与 v2 域名接口使用各自的成功契约;
    • AppKey 只保存在服务端,不进入前端代码和普通日志;
    • 保存最终 URL 、检测策略、缓存标记、实际数据时间和原始状态;
    • WHOIS 缺失字段保持 unknown ,不伪造默认值;
    • 任一子检查失败时,其他可信结果仍能进入报告;
    • 告警结合硬故障、历史基线、连续次数和页面重要性;
    • 重试有次数上限,新失败不会覆盖上一轮有效结果。

    SEO 自动巡检的目标不是制造更多分数,而是把页面、域名和历史变化组织成一份有证据、有人负责、能够执行的行动清单。

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1676 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 16:27 · PVG 00:27 · LAX 09:27 · JFK 12:27
    ♥ Do have faith in what you're doing.