來源 | 后端技術指南針
頭圖 | 圖蟲

寫在前面
今天準備和盆友們一起學習下關于通用搜索引擎的一些技術點。
鑒于搜索引擎內容非常多,每一部分都夠寫好幾篇文章的所以本文只是拋磚引玉,深入挖掘還得老鐵們親力親為。
通過本文你將對通用搜索引擎的基本原理和組成有一個較為清晰的認識,用心讀完,肯定有所收獲!
廢話不說,各位抓緊上車,沖鴨!

初識搜索引擎
2.1 搜索引擎分類
搜索引擎根據其使用場景和規模,可以簡單分為兩大類:
-
通用搜索引擎
通用搜索又稱為大搜,諸如谷歌、百度、搜狗、神馬等等都屬于這一類。

-
垂直搜索引擎
垂直搜索又稱為垂搜,是特定領域的搜索,比如用QQ音樂搜周杰倫的歌等。

兩類搜索引擎雖然數據規模和數據特征不一樣,但都是為了填平用戶和海量信息之間的鴻溝。

2.2 搜索和推薦
搜索和推薦經常被相提并論,但是二者存在一些區別和聯系。
-
共同點
宏觀上來說,搜索和推薦都是為了解決用戶和信息之間的隔離問題,給用戶有用的/需要的/喜歡的信息。
-
區別點
搜索一般是用戶主動觸發,按照自己的意圖進行檢索,推薦一般是系統主動推送,讓用戶看到可能感興趣的信息。

2.3 搜索引擎評價標準
我們每天都和搜索引擎打交道,評價一個搜索引擎的好壞可簡單概括為:精準性、時效性、響應速度、權威性等。
換句話說,搜索引擎懂得用戶真正想要找什么,可以快速準確地展示出來,對于一些熱點突發信息也可以及時收錄展示,就能很好地博得用戶。
這個目標需要搜索引擎多個模塊協作處理,是個復雜的系統工程,并非易事。

通用搜索引擎的整體概覽
3.1 搜索引擎的基本流程
大白嘗試用樸實的語言來整體表達下,通用搜索引擎大致是怎么工作的:
1. 網絡蜘蛛爬蟲每天不辭辛苦地收錄網頁,然后存儲起來,這樣各個站點的頁面就有了一份份鏡像,這個規模是百億/千億級的。

2. 單純地鏡像也不能直接用,需要加工處理,把一個個網頁進行分詞,建立搜索詞和網頁的對應關系,這樣用戶搜索某個東西時,才會拿到很多相關的網頁。

3. 比如"搜索隱秘的角落"可能會有100個相關網頁被找到,但是網頁和檢索詞的關聯性肯定有強有弱,因此還需要進行網頁的排序,排序策略有很多,最終把優質的網頁排在前面展示給用戶。

用戶看到相關結果之后,進行點擊或者跳過,搜索引擎根據用戶的相關動作進行調整,實現整個閉環過程。
4. 為了能更好地理解用戶的真實用途,需要進行檢索詞的意圖理解、詞條切分、同義詞替換、語法糾錯等處理,再根據這些檢索詞去獲取數據,為用戶找到心中所想的網頁。
比如檢索詞為"老鷹",可能是自然界的老鷹,也可能是NBA的一只球隊:

3.2 搜索引擎的基本組成
我們從整體簡單看下基本組成以及各個模塊的主要功能:

-
網絡爬蟲模塊
搜索引擎中的網絡爬蟲就是網頁的搬運工,負責將互聯網上允許被抓取的網頁進行下載,如果把搜索引擎看作一家餐廳,網絡爬蟲模塊就是餐廳的采購員。
-
內容處理模塊
負責將網絡爬蟲下載的頁面進行內容解析、內容清洗、主體抽取、建立索引、鏈接分析、反作弊等環節。
-
內容存儲模塊
存儲模塊是搜索引擎的堅強后盾,將抓取的原始網頁、處理后的中間結果等等進行存儲,這個存儲規模也是非常大的,可能需要幾萬臺機器。
-
用戶解析模塊
用戶模塊負責接收用戶的查詢詞、分詞、同義詞轉換、語義理解等等,去揣摩用戶的真實意圖、查詢重點才能返回正確的結果。
-
內容排序模塊
結合用戶模塊解析的查詢詞和內容索引生成用戶查詢結果,并對頁面進行排序,是搜索引擎比較核心的部分。
接下來,我們將粗淺地介紹幾個模塊的基本內容和技術點。

網絡爬蟲模塊簡介
網絡爬蟲模塊是通用搜索引擎非常的基礎組件,一般都會采用分布式爬蟲來實現,我們來看看這個搬運工是如何實現海量網頁發掘的:

網絡爬蟲的基本流程:
-
將熱門站點的優質URL作為種子,放到待抓取的URL隊列中
-
讀取待抓取URL獲取地址進行下載
-
將下載的網頁內容進行解析,將網頁存儲到hbase/hdfs等,并提取網頁中存在的其他URL
-
發掘到新的URL進行去重,如果是未抓取的則放到抓取隊列中
-
直到待抓取URL隊列為空,完成本輪抓取
在抓取過程中會有多種遍歷策略:深度優先遍歷DFS、廣度優先遍歷BFS、部分PageRank策略、OPIC在線頁面重要性計算策略、大站優先策略等。

在工程實踐中需要根據自身情況和搜索引擎特點進行選擇某種策略或者多種策略組合。
網絡爬蟲需要遵循Robots協議(網絡爬蟲排除標準),這是網絡爬蟲和站點之間的君子協定,站點通過協議告訴網絡爬蟲哪些可以抓哪些不可以。
網絡爬蟲同時需要考慮抓取頻率,防止給站點造成過重負擔,總之,搜索引擎的網絡爬蟲需要是個謙謙君子。

網頁內容處理模塊
爬蟲模塊將網頁內容存儲之后,網頁內存處理模塊開始解析網頁內容,主要工作包括:數據清洗、網頁內容分詞、建立正排索引、建立倒排索引等。

5.1 數據清洗
一般來說,網頁中除了具體內容還會有很多無關的東西,比如html標簽、推廣等,這些在實際搜索引擎中都是無用的。

內容處理模塊會將無用數據、標簽清洗掉,為后續的分詞做準備。
5.2 中文分詞
將清洗完成的內容進行分詞提取關鍵詞,比如一個網頁內容有1000字,分詞之后大約有50個詞,相當于提取了網頁的主干,并且會對標題、摘要、正文等不同部分的內容做不同權重處理。
分詞過程中會剔除停用詞、虛詞等,比如"的、得、地"等,從而極力還原網頁的主干內容。
我們用在線網頁分詞工具和真實網頁來模擬下這個過程:
網頁分詞在線工具:http://www.78901.net/fenci/
抓取網頁:https://tech.huanqiu.com/article/3zMq4KbdTAA

可以看到分詞后可以標注詞頻,這些都是后續作為網頁排序的重要來源,但是中文是很復雜的,因此分詞算法會有很多種,常見的包括:
-
基于字符串匹配的分詞算法
-
基于概率統計的分詞算法
-
基于語義規則的分詞算法
-
其他算法

5.3 正排索引
假定我們將每個網頁進行唯一編號docid,經過前面的分詞一個網頁將被分成不同權重的多個實體詞。
所謂正排就是根據docid可以拿到屬于該網頁的所有內容,是一個符合我們思維的正向過程,相對而言會有倒排索引。
我們以一篇《隱秘的角落》劇情簡介的頁面為例,模擬分詞情況,大致如下(本分詞結果純屬腦補,以實際為準):

5.4 倒排索引
假如我們對10000個網頁進行了分詞,其中包含了一些公共檢索詞:微山湖、智取威虎山、三十而立、隱秘的角落等,因此我們匯總之后將建立檢索詞->網頁的映射關系。

那么對于檢索詞"隱秘的角落"出現很多個網頁,倒排索引就相當于從一個詞能拉取到多少文章的過程。

就如同我們提到美食就想到:火鍋、燒烤、烤鴨、炒菜等等,是一個從點到面的過程,這種逆向過程在搜索引擎中非常重要。

5.5 本章小結
內容處理模塊將抓取到的網頁進行清洗、提前新URL給爬蟲模塊、內容分詞、建立正排索引和倒排索引,是個承上啟下的中間環節。
特別地,提一下正排索引和倒排索引,字面上并不直觀,其實道理并不難理解:
正排索引:具體到一篇網頁有多少關鍵詞,特指屬于該網頁本身的內容集合,是一個網頁。
倒排索引:一個檢索關鍵詞對應多少相關聯的網頁,也就是可備選網頁集合,是一類網頁。

網頁排序和用戶模塊
6.1 網頁排序的必要性
由于存儲的網頁是百千億級的,那么一個檢索詞可能對于幾萬、幾十萬甚至更多相關的網頁。
網頁排序需要綜合考慮:相關性、權威性、時效性、豐富度等多個方面。
搜索引擎要展示優質的強關聯網頁給用戶,并且放在靠前的位置,否則搜索效果將會很差,用戶并不買賬。
事實上也是如此,比如搜索引擎返回了10頁結果,每頁10條,總結100條,一般用戶點擊到1-3頁之后的網頁大概率就不再點擊了,因此排序的頭部內容對于搜索結果至關重要。
我們仍然以檢索"隱秘的角落"為例,百度共計返回了10頁,其中1-2頁的內容是強關聯的,是個比較不錯的檢索結果了:

6.2 網頁排序的常見策略
網頁排序策略是個不斷優化和提升的演進過程,我們來一起看下都有哪些排序策略:
-
基于詞頻和位置權重的排序
這是早期搜索引擎常采取的方法,相對簡單但是效果還不錯。
簡單來說就是根據網頁中關鍵詞的出現頻率以及出現位置作為排序依據,因為普遍認為:檢索詞出現次數越多、位置越重要,網頁的關聯性越好,排名越靠前。
詞頻并不是單純的統計次數,需要有全局觀念來判斷關鍵詞的相對次數,這就是我們要說的TF-IDF逆文檔頻率,來看下百度百科的解釋:
TF-IDF (term frequency–inverse document frequency)是一種用于信息檢索與數據挖掘的常用加權技術。
TF是詞頻(Term Frequency),IDF是逆文本頻率指數(Inverse Document Frequency)。
TF-IDF是一種統計方法,用以評估一字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。
字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著它在語料庫中出現的頻率成反比下降。
舉個栗子:
網頁中"吃飯"這個詞出現了10次,雖然次數很多,但是"吃飯"這個詞過于普通,因為在很多其他網頁都出現了,因此"吃飯"這個檢索詞的重要性就相對下降了。
-
基于鏈接分析的排序
鏈接分析排序認為:網頁被別的網頁引用的次數越多或者越權威的網頁引用,說明該網頁質量越高。

基于鏈接分析的排序算法有很多種,其中最有名的PageRank算法被谷歌廣泛采用,是其核心排序算法。
來看下PageRank算法的基本思想:
網頁的重要程度用PageRank值來衡量,網頁的PageRank值體現在兩個方面:引用該網頁其他網頁個數和引用該頁面的其他頁面的重要程度。
假定一個網頁A被另一個網頁B引用,網頁B就將PageRank值分配給網頁B所引用的網頁,所以越多引用網頁A則其PageRank值也就越高。
另外網頁B越重要,它所引用的頁面能分配到的PageRank值就越多,網頁A的PageRank值也就越高越重要。
其實這個算法說起來非常簡單:比如寫公眾號,有大V轉載就相當于引用了,越多其他公眾號轉載,說明你的公眾號內容質量越高。

PageRank算法也存在一定的問題,比如對新頁面不友好,新頁面暫時沒有被大量引用,因此PageRank值很低,并且PageRank算法強調網頁之間的引用關系,對網頁本身的主題內容可能重視程度不夠,也就是所謂的主題漂流問題。
與PageRank算法類似于的還有一些其他算法來彌補主題關聯問題,包括:HillTop算法、Topic-Sensitive PageRank算法、HITS算法等,本文就不再展開了。
6.3 網頁反作弊和seo
搜索引擎也存在二八原則,頭部的網頁占據了大量的點擊流量,也意味著巨大的商業價值。
這里就要提到SEO,先看下百度百科對SEO的定義:
搜索引擎優化又稱為SEO,即Search Engine Optimization,它是一種通過分析搜索引擎的排名規律,了解各種搜索引擎怎樣進行搜索、怎樣抓取互聯網頁面、怎樣確定特定關鍵詞的搜索結果排名的技術。
搜索引擎采用易于被搜索引用的手段,對網站進行有針對性的優化,提高網站在搜索引擎中的自然排名,吸引更多的用戶訪問網站,提高網站的訪問量,提高網站的銷售能力和宣傳能力,從而提升網站的品牌效應。
道高一尺魔高一丈,只有魔法可以打敗魔法。

網頁反作弊是搜索引擎需要解決的重要問題,常見的有內容反作弊、鏈接分析反作弊等。

-
網頁內容作弊
比如在網頁內容中增加大量重復熱詞、在標題/摘要等重要位置增加熱度詞、html標簽作弊等等,比如在一篇主題無聯系的網頁中增加大量"隱秘的角落"熱度詞、增加<strong> 等強調性html標簽。
-
鏈接分析作弊
構建大量相互引用的頁面集合、購買高排名友鏈等等,就是搞很多可以指向自己網頁的其他網頁,從而構成一個作弊引用鏈條。
6.4 用戶搜索意圖理解
用戶模塊直接和用戶交互,接收用戶的搜索詞,準確理解用戶的搜索意圖非常重要。
實際上用戶的輸入是五花八門的,偏口語化,甚至有拼寫錯誤、并且不同背景的用戶對同一個檢索詞的需求不一樣、無爭議檢索詞的使用目的也不一樣。

-
檢索詞為:美食宮保雞丁
這個檢索詞算是比較優質了,但是仍然不明確是想找飯店去吃宮保雞丁?還是想找宮保雞丁的菜譜?還是想查宮保雞丁的歷史起源?還是宮保雞丁的相關評價?所以會出現很多情況。
-
檢索詞為:你說我中午遲點啥呢?
口語化檢索詞并且存在錯別字,其中可能涉及詞語糾錯、同義詞轉換等等,才能找到準確的檢索詞,進而明確檢索意圖,召回網頁。

全文總結
搜索引擎是個非常復雜的系統工程,涉及非常多的算法和工程實現,本文旨在和大家一起簡單梳理搜索引擎的基本組成和運行原理,算是科普文章了。
搜索引擎中每一個模塊做好都不容易,也是互聯網產品中技術含金量的典型代表,深挖一個模塊都受益匪淺。