跳到主要内容

它是怎么工作的

从一个没人知道的网址,到它出现在搜索结果里,中间有五步:发现 → 抓取 → 抽取 → 索引 → 排序。这一页把五步各过一遍,排序和安全搜索单独成页。

1. 发现​

页面从两个来源进来:

  • 顺着链接走 —— 从一个已知的首页出发,把页面里的链接收集起来,一层层往外展开;
  • 站点自己声明的 —— 站点根目录有 sitemap.xml 的话优先读它(sitemapindex 会往下递归)。

robots.txt 在这一步就起作用:不允许抓的地址根本不会进队列。页面上的 rel="nofollow" 链接也在这一步直接丢掉。

2. 抓取​

  • 只取服务器直接返回的 HTML,不执行 JavaScript。
  • 同一个域名两次请求之间至少隔 2 秒;站方在 robots.txt 里写了 Crawl-delay 就按更大的那个来。
  • 内容没变的页面不重复保存:支持 ETag / Last-Modified,没变时服务器只需回一个 304,页面不用重传。
  • 抓不到也分几种情况:被站点明确挡住(robots 屏蔽,或者人机验证过不去)会留一条说明记录;域名解析不了、服务器报错这类则等下一次,不硬敲。

3. 抽取​

一页 HTML 里真正有用的部分往往不到十分之一,得先把它拆出来:

  • 正文 —— 先收链接,再剁掉导航、页脚、侧边栏、评论区,然后在剩下的容器里挑文字最多的那个。
  • 摘要 —— 取正文里段落(<p>)优先的开头一段。不直接截前 220 个字,是因为容器拍平之后信息框、导航框会排在正文前面,截出来就是一堆字段的拼盘;按段落取最接近「这一页在讲什么」。
  • 正文上限 —— 一个页面只保留前 2000 字参与匹配。这是索引体积和检索范围的折中:绝大多数页面的主题词都在开头,代价是长文中段的具体词我们搜不到。
  • 页面自己的声明 —— <meta name="robots"> 和 X-Robots-Tag 响应头合起来判,跟 robots.txt 一样有效。noindex 是这一页不入库、但照样跟进它的链接;nofollow 才是不跟这一页上的链接。

4. 索引​

留下的东西进索引库:标题、描述、摘要、正文前 2000 字,加上站点名和地址。索引用 Meilisearch 建,跑在我们自己的服务器上。

两处刻意的设置:

  • 站名和域名也是可搜字段,但位置排在标题和描述之后 —— 这样「标题里有这个词」永远压过「只是站名或域名里含这个词」。
  • 关掉了前缀匹配。这是为了「Redis 不会被 Redistribution 撞上」这类误命中让路。代价是拉丁词打一半搜不到,中文不受影响。

5. 排序​

命中的页面可能几十万个,谁排前面取决于相关性、站点权重、权威度、同站折叠和一点用户反馈 —— 单独一页讲:结果是怎么排出来的。

最后一道:安全搜索​

排序定完之后还有一层过滤,挡成人内容和垃圾站点,四档可选、默认「均衡」:安全搜索。