搜索推薦技術(shù)在電商導(dǎo)購領(lǐng)域的應(yīng)用(二):爬蟲

2015-11-11 09:31:00 來源:Pmcaff 作者:佚名 人氣: 次閱讀 176 條評論

爬蟲只是一種形象的比喻,不是樹上爬來爬去的那種……爬蟲是一種自動獲取網(wǎng)頁內(nèi)容的程序,是搜索引擎的重要組成部分,是數(shù)據(jù)處理的第一個環(huán)節(jié)。大體上,可以有傳統(tǒng)和垂直兩...

搜索引擎爬蟲 <a href=/tech/biz/ target=_blank class=infotextkey>電商</a>搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

文/高揚

什么是爬蟲?

爬蟲只是一種形象的比喻,不是樹上爬來爬去的那種……爬蟲是一種自動獲取網(wǎng)頁內(nèi)容的程序,是搜索引擎的重要組成部分,是數(shù)據(jù)處理的第一個環(huán)節(jié)。大體上,可以有傳統(tǒng)和垂直兩種類型,傳統(tǒng)的就是google、baidu大搜索爬蟲,本篇介紹是的電商垂直爬蟲。

做一個簡單的爬蟲很容易,你只要寫下面這行代碼:

wget http://www.meituan.com/

完了……

看,很簡單吧,大家都覺得寫一個爬蟲很簡單,也預(yù)示著爬蟲攻城濕苦逼日子的開始……

上面這行代碼給學(xué)生講講課是夠用的,但實戰(zhàn)還需要解決很多問題,爬蟲的基本工作有抓取、抽取、存儲,我們分別說一說。

(一)抓取

1. 編碼識別&翻頁

互聯(lián)網(wǎng)上的網(wǎng)頁大多是http協(xié)議的,但編碼每家都不一樣,有utf-8,gbk,gb2312等等。如果無視編碼問題,會使部分網(wǎng)頁下載后是亂碼,導(dǎo)致無法使用。

通常網(wǎng)頁head標簽內(nèi)會標記編碼,例如搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù),但總有不靠譜的網(wǎng)站維護者不遵守標準,實際編碼并不一定是utf8的。我們研發(fā)了一種通用技術(shù)解決方案:編碼智能識別。我們內(nèi)置了每個編碼的常用字符集二進制碼,然后將網(wǎng)頁內(nèi)容二進制化,找出匹配度最大的,作為這個網(wǎng)頁的真正編碼。這個方法很有效,99%+的準確率,就是稍微耗費點CPU,我們基本都用這個方法來識別網(wǎng)頁編碼,無視charset標簽。

另外,很多電商商品頁面,部分區(qū)域是ajax異步加載的,用POST的也比較多,直接使用wget、curl有諸多不便,需要支持。我們對其進行了整體封裝,內(nèi)部稱這個類庫為httpfetcher。

2. 智能的調(diào)度、更新

電商網(wǎng)頁變化比較頻繁,特別是商品價格字段,有時候幾乎幾分鐘一變。上億的商品庫做到每個商品都能及時更新是很困難的,如何用有限資源,抓取最應(yīng)該更新的商品,是一個難題。以商品更新為例,我們采用基于賣場場景的調(diào)度方式,不同的賣場場景更新頻率不同,每一個爬蟲負責(zé)特定場景的抓取任務(wù),稱作一個環(huán)。發(fā)現(xiàn)環(huán)負責(zé)粗粒度發(fā)現(xiàn),更新環(huán)負責(zé)粗粒度更新,秒殺環(huán)負責(zé)限時搶購類的細粒度更新,如下圖

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

3. 重復(fù)抓取規(guī)避

帶寬,恩,帶寬……一談到帶寬,爬蟲濕都雙眉緊鎖。創(chuàng)業(yè)小公司,不是BAT那種不差錢的主,在北京這種地方帶寬是很貴滴,如果能省下一點點帶寬,那年終獎都出來了滴。gzip壓縮這種優(yōu)化標準套餐后,我們還需要解決重復(fù)網(wǎng)頁抓取,節(jié)約帶寬。

我們管理的網(wǎng)址是億級別的,普通hashmap在內(nèi)存中存不下,需要使用BloomFilter了。

BloomFilter是一種空間效率很高的隨機數(shù)據(jù)結(jié)構(gòu),它利用位數(shù)組很簡潔地表示一個集合,并能判斷一個元素是否屬于這個集合。

下面我們具體來看Bloom Filter是如何用位數(shù)組表示集合的。初始狀態(tài)時,Bloom Filter是一個包含m位的位數(shù)組,每一位都置為0。

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

為了表達S={x1, x2,…,xn}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的哈希函數(shù)(Hash Function),它們分別將集合中的每個元素映射到{1,…,m}的范圍中。對任意一個元素x,第i個哈希函數(shù)映射的位置hi(x)就會被置為1(1≤i≤k)。注意,如果一個位置多次被置為1,那么只有第一次會起作用,后面幾次將沒有任何效果。在下圖中,k=3,且有兩個哈希函數(shù)選中同一個位置(從左邊數(shù)第五位)。

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

在判斷y是否屬于這個集合時,我們對y應(yīng)用k次哈希函數(shù),如果所有hi(y)的位置都是1(1≤i≤k),那么我們就認為y是集合中的元素,否則就認為y不是集合中的元素。下圖中y1就不是集合中的元素。y2或者屬于這個集合,或者剛好是一個false positive。

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

BloomFilter的這種高效是有一定代價:

1. 在判斷一個元素是否屬于某個集合時,有可能會把不屬于這個集合的元素誤認為屬于這個集合(falsepositive)。不過對于爬蟲場景,來判斷一個網(wǎng)址是否被抓取過來說,這種誤判率是可以接受的。

2. 無法unset。如果一個網(wǎng)頁較早前被抓取過,因為某種原因想再抓一次,Bloom Filter下無法重新清狀態(tài)再抓取。我們在實踐中,采用的是定期清空Bloom Filter,在帶寬浪費和unset之間做了一個平衡。

此外,抓取還要解決防封禁等。

(二)抽取

垂直爬蟲所涉及的網(wǎng)頁空間相對比較集中,對數(shù)據(jù)結(jié)構(gòu)化要求較高,需要通過模板來解決。我們定義并使用了四種模板:URL模板,列表模板,商品模板和點評模板,這里簡單說說前三種。

URL模板

1. URL歸一化

商品URL可以標識一個唯一商品,在網(wǎng)站上同一個商品可能有不同的url,原因可能多方面的,一是入口不一樣,列表頁,搜索頁點擊過去的頁面是不一樣的,二是URL后面經(jīng)常帶有統(tǒng)計信息。這樣會導(dǎo)致庫里大量的商品重復(fù)以及Bloom Filter失效,所以需要采用某種規(guī)則,將這些URL轉(zhuǎn)化為同一類型的URL,被我們成為URL歸一化。

2. URL特征

制定不同的規(guī)則來判定是列表url還是商品url,方便采取不同的抓取策略。列舉一些URL模板例子:

商品URL模板

www.jd.com|^/product/[0-9]+/.html.*$

book.jd.com|^/[0-9]+/.html.*$

列表模板

表明當(dāng)前的為一個列表模板,需要通過模板獲取的信息為商品總頁數(shù)

一個列表鏈接意味著這個鏈接上面都是一個跳出的鏈接,通過獲取所有的鏈接,然后與當(dāng)前網(wǎng)站商品的URL特征匹配,可以獲得純凈的商品URL鏈接,從而控制了發(fā)現(xiàn)的鏈接的準確性。

當(dāng)一個頁面可以翻頁的時候,種子URL模板如下

http://www.jd.com/products/652-828-1107-0-0-0-0-0-0-0-1-5-[xx].html

爬蟲收到這種類型的鏈接,按照初始默認起始頁,步長爬起第一個頁面。

http://www.jd.com/products/652-828-1107-0-0-0-0-0-0-0-1-5-1.html。爬取完畢以后,通過列表模板獲得商品總頁數(shù),寫入到鏈接對象持久化。然后將這個鏈接新發(fā)現(xiàn)的商品鏈接和自身寫入URLDB。當(dāng)爬蟲在次從URLDB取到這個鏈接時,發(fā)現(xiàn)這個鏈接是可以翻頁的連接,于是按照當(dāng)前的pageIndex,pageStep計算出下一個頁面。然后爬取下一個頁面。

商品模板

早期商品模板主要使用Xpath正則、JS子模板及自定義的表達式來完成商品信息的解析。Xpath正則很常見,自行百度。JS子模板主要用來解決一些技術(shù)的問題

1,實現(xiàn)在解析某個頁面時調(diào)用其子頁面(ajax),因為有時某些商品信息(如點評量),在商品頁的html代碼中是不存在的,需要調(diào)用該商品頁的子頁面(如點評頁)才能獲取;

2,實現(xiàn)從頁面中抽取內(nèi)容傳遞給某個中間變量(虛擬的模板項),因為有時某個最終結(jié)果需要同時對兩個中間結(jié)果做處理才能得到,需要支持創(chuàng)建多個中間變量。

JS子模板這個名字不好,最初未來解決javascript帶來的問題,后面也就懶得改了。隨著技術(shù)的迭代優(yōu)化,逐漸使用一種自研的腳本語言(內(nèi)部代號,behemoth)來簡化模板抽取工作。鑒于腳本語言的靈活性,behemoth幾乎能做到任何程度的處理,可用來抽取商品SKU,點評等。目前我們正逐漸替換成behemoth。

behemoth極大簡化了模板編寫工作,隱藏諸多技術(shù)信息(例如常用的xpath、正則封裝),讓模板編寫者只關(guān)注業(yè)務(wù)邏輯。此外,大多數(shù)電商網(wǎng)頁,都存在著盤根交錯的ajax調(diào)用,behemoth先執(zhí)行整個網(wǎng)頁的dom渲染后再進行抽取工作,每個抽取模板是一個code unit,極大降低了模板編寫復(fù)雜度。

behemoth也是有代價的,由于大量的渲染工作,抽取一個網(wǎng)頁的時間是之前的幾倍??傮w上,好處還是大于壞處。

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

這是我們早期一些模板的示例。

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

這是目前模板的演化現(xiàn)狀。

對了,還有一個問題,模板這么多,如果模板失效了怎么檢測呢?我們?yōu)榇搜邪l(fā)了一個自動檢查機器人,將有問題的模板定期挑出來,讓人工修改更新。這種架構(gòu),維護幾千家網(wǎng)站不成問題。

此外,我們正在研發(fā)第三代抽取技術(shù),模板工作將會進一步再減少50%+。

(三)存儲

需要管理的網(wǎng)址鏈接是百億級,商品是10億級,為了方便分析和讀取,需要支持隨機寫和順序?qū)懙拇鎯?a href=/pc/system/ target=_blank class=infotextkey>系統(tǒng),關(guān)系型數(shù)據(jù)無法滿足我們的需求,需要no-sql型。早期我們自研了一套文件系統(tǒng)——ministore,隨著數(shù)據(jù)量的增長,維護的成本比較高,中期我們且換到了Cassandra,到現(xiàn)在我們使用改造后的Hadoop+redis。有關(guān)Cassandra、Redis、Hadoop文章很多,兩個系統(tǒng)各有特點,這里不展開說。

小結(jié)

搜索引擎爬蟲 電商搜索優(yōu)化 電商搜索引擎 搜索技術(shù)

要寫好一個爬蟲要干這么多活,絕對是一個臟活累活有木有,堪稱技術(shù)界的活雷鋒有木有。

一個優(yōu)秀的爬蟲對搜索引擎發(fā)揮著極其重要的作用,它是核心數(shù)據(jù)的源頭,處理的越好,對后續(xù)的處理幫助越大。

    無相關(guān)信息