聊聊百度搜索背后的故事
聊聊 “吳牙簽” 背后的搜索引擎技術(shù)
大家好,我是魚皮,今天分享點(diǎn)有趣的技術(shù)知識(shí)。
前兩天,我想上網(wǎng)買包牙簽,于是就打開了某度搜索。
結(jié)果讓我懵逼,我搜到的第一條內(nèi)容竟然不是拿來剔牙的工具,而是搜出了一位明星,江湖美譽(yù) “吳牙簽”。

原來是最近的一個(gè)大瓜,你看這個(gè)簽它又細(xì)又扎 ?? ~

在吃瓜的同時(shí),問題來了:為什么搜索牙簽時(shí),最先搜出來的不是傳統(tǒng)牙簽而是老吳呢?
作為一名程序員,有必要給大家科普一下互聯(lián)網(wǎng) 搜索引擎
的工作原理,看看它是怎么幫助我們從數(shù)億個(gè)網(wǎng)站中精準(zhǔn)地把這根牙簽找出來的!
搜索引擎工作原理
內(nèi)容參考百度官方的搜索引擎工作原理介紹
先放一張官方的搜索引擎工作流程圖:

看不懂沒關(guān)系,下面用實(shí)際的例子帶大家理解。
數(shù)據(jù)抓取
用戶搜索網(wǎng)站的內(nèi)容歸根結(jié)底是來自于存儲(chǔ)網(wǎng)站的數(shù)據(jù)庫的,因此,搜索引擎做的第一件事肯定是先把各個(gè)網(wǎng)站的數(shù)據(jù)抓到手。
當(dāng)然,數(shù)據(jù)的抓取不可能全部交給人工負(fù)責(zé),更多的是讓機(jī)器(程序)自動(dòng)抓取。通常,我們把負(fù)責(zé)數(shù)據(jù)抓取的工具人叫做 spider
,即網(wǎng)頁蜘蛛。
每個(gè)搜索引擎都有自己的蜘蛛,各家的蜘蛛行為也不同,但基本原理是類似的。
整個(gè)互聯(lián)網(wǎng)就是一張大蜘蛛網(wǎng),網(wǎng)頁中又嵌套著網(wǎng)頁。網(wǎng)頁蜘蛛就順著網(wǎng)爬(類似有向圖),從入口開始,通過頁面上的超鏈接關(guān)系,不斷發(fā)現(xiàn)新的網(wǎng)址并抓取,目標(biāo)是盡最大可能抓取到更多有價(jià)值網(wǎng)頁。
比如有位作者寫了一篇 “吳牙簽” 相關(guān)的文章,發(fā)到了某個(gè)寫作平臺(tái),網(wǎng)頁蜘蛛就能順著這個(gè)寫作平臺(tái)將這篇文章抓到自己的網(wǎng)頁數(shù)據(jù)庫中。

聽起來好像還挺簡(jiǎn)單的,但對(duì)于億級(jí)數(shù)據(jù)量的搜索引擎,需要有很多額外的考慮。
需關(guān)注的問題
首先是 重復(fù)和失效 問題,對(duì)于類似百度這樣的大型 spider 系統(tǒng),因?yàn)殡S時(shí)都存在網(wǎng)頁被修改、刪除、失效或出現(xiàn)新的超鏈接的可能。因此,不是把網(wǎng)站抓取過來就完事了,而是要維護(hù)一個(gè)網(wǎng)址庫和頁面庫,保證庫內(nèi)網(wǎng)頁的真實(shí)有效、不冗余。
還有其他問題比如:
如何保證抓取網(wǎng)站的質(zhì)量?應(yīng)拒絕垃圾廣告、不良信息網(wǎng)站。
如何保證抓取友好性?應(yīng)控制蜘蛛抓取的頻率和深度,別蜘蛛太重把整個(gè)網(wǎng)搞破了。
如何使抓取的覆蓋度更大?抓取一些原本抓不到的數(shù)據(jù)孤島。
當(dāng)然,問題遠(yuǎn)遠(yuǎn)不止這些,設(shè)計(jì)搜索引擎的抓取系統(tǒng)還是很復(fù)雜的,協(xié)議、算法、策略、原則、異常處理都要納入考慮。以下是百度官方提供的抓取系統(tǒng)基本框架圖,展示了抓取系統(tǒng)的宏觀工作流程:

抓取配額
假如我們做了一個(gè)網(wǎng)站,肯定希望其他同學(xué)能搜到對(duì)吧。那么最關(guān)鍵的一點(diǎn)就是先讓蜘蛛抓到你、并且多抓你。
通常,數(shù)據(jù)抓取系統(tǒng)會(huì)綜合評(píng)估站點(diǎn)來確定抓取次數(shù)和頻率。
像百度搜索引擎主要是根據(jù) 4 個(gè)指標(biāo)來確定:
網(wǎng)站更新頻率:更新越頻繁的網(wǎng)站,蜘蛛抓取頻率越高
網(wǎng)站更新質(zhì)量:內(nèi)容質(zhì)量越高的網(wǎng)站,蜘蛛抓取的越多
連通度:蜘蛛要能順利抵達(dá)該網(wǎng)站,且能正常訪問
站點(diǎn)評(píng)價(jià):運(yùn)用算法對(duì)站點(diǎn)進(jìn)行一個(gè)打分,也會(huì)影響收錄度
數(shù)據(jù)處理
在蜘蛛抓取到網(wǎng)頁,并存入網(wǎng)頁數(shù)據(jù)庫后,并不能把這一大坨網(wǎng)頁數(shù)據(jù)直接拿來用。
比如我要搜索 “老吳牙簽”,網(wǎng)頁數(shù)據(jù)庫中可能存儲(chǔ)了數(shù)以億計(jì)個(gè)網(wǎng)站,而且網(wǎng)站中又有那么多牙簽,我怎么知道哪根是老吳的?
雖然慢慢搜肯定能搜出結(jié)果,但別忘了用戶可等不起!現(xiàn)在大家對(duì)網(wǎng)站的要求很高,幾秒鐘沒搜出來大家可能就會(huì)懷疑網(wǎng)絡(luò)了。因此搜索引擎必須要面臨的挑戰(zhàn)是:如何提高搜索網(wǎng)頁的效率?最好是在毫秒級(jí)完成。
為了實(shí)現(xiàn)這點(diǎn),搜索引擎首先會(huì)對(duì)亂七八糟的網(wǎng)頁數(shù)據(jù)進(jìn)行 頁面分析 ,將原始頁面的不同部分進(jìn)行識(shí)別并標(biāo)記。比如幾個(gè)影響搜索的關(guān)鍵字段:網(wǎng)頁的 title(標(biāo)題)、keywords(關(guān)鍵詞)、description(摘要)等。
<html>
??<title>老吳賣牙簽</title>
??<meta?name="keywords"?content="娛樂,生活,很大">
??<meta?name="description"?content="老吳賣牙簽">
</html>
提取出這些信息后,僅通過傳統(tǒng)的關(guān)系型數(shù)據(jù)庫和順序搜索算法是無法滿足毫秒級(jí)查詢的。那不妨換個(gè)思路。既然用戶都是根據(jù)關(guān)鍵詞搜索,那如果事先知道這些關(guān)鍵詞存在于哪些頁面中,不就能直接找到了么?即對(duì)內(nèi)容進(jìn)行 分詞
,建立 倒排索引
。
分詞就是把一句話拆分成多個(gè)單詞,英文分詞比較簡(jiǎn)單,就根據(jù)空格來就行。但中文分詞就麻煩了,傳統(tǒng)分詞方法是建立一個(gè)詞典,然后線性匹配,但這種方法成本大、且精度不高?,F(xiàn)在基本都是 NLP(自然語言處理)、AI 分詞了,包括了切詞、同義詞轉(zhuǎn)換、同義詞替換等等。
以對(duì)頁面標(biāo)題分詞為例,比如有兩個(gè)網(wǎng)頁,第一個(gè)網(wǎng)頁的標(biāo)題是 “老吳賣牙簽”,其實(shí)會(huì)被分詞為 “老吳”、“賣”、“牙簽”。第二個(gè)網(wǎng)頁的標(biāo)題是 “老吳牙簽很大”,會(huì)被分詞為 “老吳”、“牙簽”、“很大”。
分詞后,要根據(jù)分詞結(jié)果建立 倒排索引
。
如果說 正向索引
就像書的目錄,幫助我們根據(jù)頁碼找到對(duì)應(yīng)章節(jié);那倒排索引則像是打小抄,事先記錄好題目答案所在的頁碼,再根據(jù)頁碼快速找到題目答案。
對(duì)上面的兩個(gè)網(wǎng)頁建立正向索引:
網(wǎng)頁 id標(biāo)題內(nèi)容1老吳賣牙簽xxx2老吳牙簽很大xxx
建立倒排索引:
索引 id索引文本存在于網(wǎng)頁 id1老吳1, 22賣13牙簽1, 24很大2
建立并存儲(chǔ)倒排索引后,如果用戶搜索關(guān)鍵詞 “很大”,只需要從倒排索引表中找到索引文本等于 “很大” 的那一行,取出包含該詞的網(wǎng)頁 id,就可以再根據(jù)網(wǎng)頁 id 去正向索引中找到網(wǎng)頁全部信息了。
數(shù)據(jù)檢索
光有倒排索引還不能支持用戶快速搜索,在最后的數(shù)據(jù)檢索環(huán)節(jié)也有大學(xué)問。
比如為什么搜索 “老吳不是牙簽”,卻能搜出 “吳牙簽” 呢?

明明前者沒有包含后者對(duì)吧,我們常用的 like、正則之類的字符串匹配算法是查詢不到結(jié)果的。
下面講講搜索引擎的做法。
先放一張幾年前由百度搜索官方提供的數(shù)據(jù)檢索流程圖,大致思路是沒問題的,但有些步驟的細(xì)節(jié)可能早已天差地別。

1. 分詞
先像建立倒排索引一樣,對(duì)用戶輸入的查詢文本進(jìn)行分詞,比如搜索 “老吳不是牙簽”,可能的分詞為:“老吳”、“不是”、“牙簽”。
2. 查詢倒排索引
分別對(duì)這 3 個(gè)關(guān)鍵詞,從事先建立好的倒排索引中查出包含網(wǎng)頁的集合:
關(guān)鍵詞包含該關(guān)鍵詞的網(wǎng)頁老吳網(wǎng)頁 1、網(wǎng)頁 2不是網(wǎng)頁 3牙簽網(wǎng)頁 1、網(wǎng)頁 2
然后將上述查詢出的網(wǎng)頁取交集(及所有關(guān)鍵詞都必須包含該網(wǎng)頁,查詢要求更嚴(yán)格)或并集(包含任一關(guān)鍵詞即可),作為候選集合。
此處為了得到更多的結(jié)果,取并集作為候選集合,結(jié)果為:網(wǎng)頁 1、網(wǎng)頁 2、網(wǎng)頁 3。
3. 相關(guān)性評(píng)價(jià)
其實(shí)就是給候選集合中的網(wǎng)頁打分,根據(jù)上一步的索引查詢結(jié)果,來計(jì)算用戶的搜索和網(wǎng)頁實(shí)際內(nèi)容到底有多像。
一種很常見的打分算法是 TF-IDF
,是搜索引擎技術(shù) Elasticsearch
和 Lucene
最主流的打分機(jī)制。在 Elasticsearch 中,將該打分算法結(jié)合向量空間模型、協(xié)調(diào)因子、詞語權(quán)重提升等,組成了 實(shí)用評(píng)分函數(shù)
,提高搜索的有效性。
TF 是 詞頻 ,就是關(guān)鍵詞在網(wǎng)頁中出現(xiàn)的頻度是多少。頻度越高,權(quán)重越高。出現(xiàn) 5 次 “牙簽” 關(guān)鍵詞的網(wǎng)頁在該詞的權(quán)重顯然比只出現(xiàn) 1 次要高。
公式如下:
//?該詞在文檔中出現(xiàn)次數(shù)的平方根
tf(t?in?d)?=?√frequency
IDF 是 逆向文檔頻率 ,即關(guān)鍵詞在集合所有網(wǎng)頁中出現(xiàn)的頻率是多少。物以稀為貴,越冷門的詞,權(quán)重反而越高。
上面的例子中顯然 “不是” 這個(gè)詞最稀有,所以 “網(wǎng)頁 3” 在這個(gè)詞的分?jǐn)?shù)會(huì)更高。
公式如下:
//?索引中文檔數(shù)量除以所有包含該詞的文檔數(shù),然后求其對(duì)數(shù)
idf(t)?=?1?+?log?(?numDocs?/?(docFreq?+?1))
此外,還有一個(gè)因素是 norm
(字段長(zhǎng)度歸一值)。假設(shè)同一個(gè)網(wǎng)頁的標(biāo)題和內(nèi)容都包含了 “牙簽”,而標(biāo)題很短,內(nèi)容很長(zhǎng),那么在標(biāo)題中出現(xiàn) “牙簽” 會(huì)有更高的權(quán)重。
//?字段中詞數(shù)平方根的倒數(shù)
norm(d)?=?1?/?√numTerms
用戶搜索文本中的 每一個(gè) 關(guān)鍵詞都要結(jié)合這些因素進(jìn)行打分,最后再結(jié)合每個(gè)詞的權(quán)重將分?jǐn)?shù)進(jìn)行累加,計(jì)算出每個(gè)候選網(wǎng)頁的最終得分。
最終公式如下:

有興趣的朋友可以閱讀《Elasticsearch:權(quán)威指南》的相關(guān)度評(píng)分章節(jié)。
地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scoring-theory.html
在上面的例子中,計(jì)算分?jǐn)?shù)后,得到的集合如下:
網(wǎng)頁標(biāo)題分?jǐn)?shù)網(wǎng)頁 1老吳賣牙簽0.9網(wǎng)頁 2老吳牙簽很大0.8網(wǎng)頁 3不是吧0.7
網(wǎng)頁 1 比網(wǎng)頁 2 雖然都匹配到了兩個(gè)關(guān)鍵詞,但前者更短,所以分?jǐn)?shù)略高一籌。
4. 過濾
上面的步驟只是計(jì)算了候選網(wǎng)頁的得分,但并不是這些網(wǎng)頁都能被搜出來,還要經(jīng)過各種過濾,比如過濾掉死鏈(失效網(wǎng)站)、重復(fù)數(shù)據(jù)、各種 “你懂的” 網(wǎng)站等。

5. 排序
經(jīng)過上面的步驟,我們最后得到了 3 個(gè)網(wǎng)頁,但到底該把哪個(gè)網(wǎng)頁放到第一位呢?
回到開頭的問題:為什么搜索牙簽時(shí),最先搜出來的不是傳統(tǒng)牙簽而是老吳呢?
這個(gè)問題取決于 最終排序 ,現(xiàn)在一般都使用機(jī)器學(xué)習(xí)算法,結(jié)合一些信息,比如上面提到的相關(guān)度、網(wǎng)站的質(zhì)量、熱度、時(shí)效性等等,將最能滿足用戶需求的結(jié)果排序在最前。
而老吳是近期的爆款內(nèi)容,在熱度、時(shí)效性、搜索相關(guān)度上都很有優(yōu)勢(shì),而且不排除有人工或推廣來動(dòng)態(tài)操作權(quán)重的可能。
相信講到這里,大家也都能理解為什么搜索牙簽時(shí), “吳牙簽” 被頂?shù)绞醉摿税蓗

搜索引擎優(yōu)化
那假如說你做了一個(gè)網(wǎng)站,肯定希望不僅其他用戶能搜到,而且是要在第一條對(duì)吧。
要做到這點(diǎn),首先要讓蜘蛛抓到你的網(wǎng)頁,還要重點(diǎn)研究搜索結(jié)果的排序機(jī)制。這些內(nèi)容結(jié)合起來,就是我們常說的 SEO(搜索引擎優(yōu)化)。
這一塊學(xué)問很大,我自己的編程導(dǎo)航網(wǎng)站目前也做到了各搜索引擎的 排名第一 ,送給大家一些 SEO 視頻教程吧。在我的博客回復(fù) seo 即可。
指路:https://t.1yb.co/qOJG
后面我會(huì)再結(jié)合實(shí)際具體講講我做 SEO 的小技巧。
以上就是本期分享。我是魚皮,歡迎閱讀 我從 0 自學(xué)進(jìn)入騰訊的編程學(xué)習(xí)、求職、考證、寫書經(jīng)歷,不再迷茫!
指路:https://t.1yb.co/w66s
點(diǎn)贊 還是要求一下的,祝大家都能心想事成、發(fā)大財(cái)、行大運(yùn)。

本文章視頻版,歡迎大家觀看:
