导航站怎么做收录审核:把死链率压到可接受的水平

做导航站的第一年,几乎所有人都踩过同一个坑:收录越来越快,死链也越来越多。

打开后台一看,3000 条记录里有 200 多条打不开,评论区开始有人反馈"点进去是空白"。这时候再回头清理,成本远高于一开始就设计好审核流程。

一、收录审核要解决的核心矛盾

用户提交链接的动机是好的,但提交的形态是极其随意的:

  • 填了首页就以为收录了具体工具
  • 填了带追踪参数的推广链接
  • 填了已经换过的旧域名
  • 填了根本打不开的地址

如果不做审核直接入库,你的目录会迅速退化成一个"谁都能塞垃圾进来"的公共书签夹。而如果审核过严,收录量上不去,用户会觉得"这站没什么东西"。

所以审核的目标不是拒绝,而是归一化——把五花八门的提交整理成规范、可用的条目。

二、三个判定层级

我们把每个提交拆成三层检查,每层的判定成本和严格度递增:

第一层:格式与可访问性(自动,几乎全通过)

检查项:

  • URL 是否可解析、协议是否为 http/https
  • 是否有明确的标题(没有就抓首页 title)
  • 首屏 HTTP 状态码是否为 200
  • 是否是明显的导航站/广告页(二级判断,可选)

这一层只是筛掉明显不合格的,不做主观判断。通过率通常在 95% 以上。

第二层:内容相关性与质量(半自动)

真正需要判断的部分:

  • 站点主题是否属于收录范围 —— 一个导航站不应该收录另一个导航站
  • 是否已经是收录过的站点 —— 这是去重的关键
  • 是否有足够的内容量 —— 只有一两个页面的站点用户体验差
  • 站点本身是否值得收录 —— 有没有实际价值,还是纯采集站

这一层可以半自动:先用规则打分(收录分类匹配度、是否已收录、页面数量、是否有备案等),把分数靠后的交给人工。

第三层:人工复核(只针对边界情况)

不是所有东西都值得人工看。我们的做法是:

  • 机器判定明确合格的 → 直接入库
  • 机器判定明确不合格的 → 直接拒绝
  • 只有机器拿不准的 → 进人工队列

人工只看队列,且只需要做一个动作:打开首页看一眼。

这个设计的关键是让人工只处理"机器不确定"的部分。如果每条都人工看,那这个流程必然崩溃——早期我们就是这么做的,结果就是审核积压,用户提交后三天看不到收录。

三、入库时的抓取控制

审核通过后要抓取标题、描述、图标,这些请求如果控制不好,容易把对方站点打挂,也可能让自己被封。

import asyncio
import random
from datetime import datetime
from urllib.parse import urlsplit

MIN_INTERVAL = 2.0       # 同一域名最小请求间隔(秒)
TIMEOUT = 8
MAX_RETRY = 2

_sem = {}
_last = {}

async def throttle(host: str):
    """同一域名串行化 + 最小间隔"""
    async with _sem.setdefault(host, asyncio.Semaphore(1)):
        prev = _last.get(host)
        if prev is not None:
            wait = MIN_INTERVAL - (datetime.now() - prev).total_seconds()
            if wait > 0:
                await asyncio.sleep(wait)
        _last[host] = datetime.now()

async def fetch_meta(url: str) -> dict | None:
    host = urlsplit(url).hostname
    for attempt in range(MAX_RETRY + 1):
        await throttle(host)
        try:
            async with httpx.AsyncClient(timeout=TIMEOUT, follow_redirects=True) as c:
                r = await c.get(url, headers={
                    "User-Agent": "Mozilla/5.0 (compatible; DirectoryBot/1.0)"
                })
                if r.status_code == 200:
                    return {"url": url, "html": r.text[:200000]}
        except Exception:
            if attempt == MAX_RETRY:
                return None
            # 指数退避 + 抖动
            await asyncio.sleep(1.5 ** attempt + random.uniform(0, 1))
    return None

几个实际参数怎么定的:

MIN_INTERVAL 用 2 秒。 更激进(比如 0.5 秒)在实际测试中会被对方站点返回 429,1 秒时偶发,2 秒后基本没有拒绝。

超时设 8 秒而不是更长。 一个打不开的站点不值得等 30 秒,超时本身就是判定信号。

重试最多 2 次。 第三次还失败基本可以判定站点不可用。

User-Agent 要标明身份。 透明的爬虫身份比伪装成浏览器更负责任,也更容易获得对方配合。

四、去重:容易漏掉的一环

审核时最常见的技术性遗漏是"同一站点多个地址"。用户可能提交:

  • example.com
  • www.example.com
  • example.com/about
  • example.com/index.html

前两个是同一站点,后两个也是。所以去重要分两层:

站点级去重:用主域名(去掉 www)作为唯一键,已存在就跳过。

路径级去重:规范化后的完整 URL 作为唯一键,规范化规则我写过一篇专门的文章。

只做站点级去重会漏掉"同一站点不同页面",但如果一个站点只允许收录一条,那就用站点级;如果允许多条(如收录多个子工具),就得做路径级。

五、效果怎么衡量

审核流程上线后,要盯这几个指标:

指标 含义 健康值
死链率 收录条目中当前不可访问的比例 低于 5%
审核通过率 提交被接受的比例 70%–90%
人工复核占比 进入人工队列的比例 低于 20%
平均入库时长 提交到可见的时间 24 小时内

人工复核占比是最值得盯的指标。 如果超过 30%,说明自动判定规则太弱,需要补充规则;低于 5% 则可能过于宽松,把低质量内容放进来了。

死链率则需要持续监控——它是滞后指标,站点关停不会主动通知你,只能靠定期复查。

小结

收录审核的核心不是"严"或"松",而是分层:格式层全通过、相关性层半自动、边界层才人工。

三个层次之外,还有两个容易被忽略但同样重要的点:抓取要控制频率(否则伤人也伤己),去重要做站点级和路径级两层(否则库里会塞满同一个站)。

把这些都做了,你的目录才会真正做到"干净、好用",而不是"什么都有但一半打不开"。

本文提到的收录审核与死链治理思路,可参考 VP导航 的公开实现方式。

posted on 2026-10-24 23:20  亿云信息科技  阅读(5)  评论(0)    收藏  举报

导航