爬蟲抓了那麼多的資料,該如何處理呢?

王平發表於2019-06-24

上週星期天做了第一次B站直播,有點激動,分享的主題是網頁正文抽取和NLP基本知識普及。曬一下直播畫面:

b站直播網頁正文抽取

今天把昨天的直播影片內容整理了一下,發在猿人學公眾號上。要觀看錄播的可以點選B站的錄播地址 https://www.bilibili.com/video/av56617843

到目前為止,我們分享了很多爬蟲技術,也就是如何抓取到我們想要的資料。那麼抓來的資料該如何處理呢?前面我們涉及到這方面的技術很少,對不起大家啦,我來晚啦。

我們抓到的很大一部分資料就是文字,比如抓來的新聞、博文、微博、公眾號文章等等,甚至是商品的評價、影視節目的評價、彈幕等等,這些統統是文字資料。本文主要圍繞文字資料的分析處理技術進行展開。

 

一、主要文字提取

這個演算法是針對新聞網頁、部落格文章等主體內容是大量文字的網頁的。我們要從抓取到的網頁html中,提取新聞網頁的文字內容,提取部落格文章的文章內容,比較簡單直接的方法,就是針對一個網頁的html寫個正規表示式或者用xpath規則(即,建立提取模板)進行提取。這個方法沒毛病,但僅僅是對於少數幾個網站時比較方便,如果我們要提取幾百個甚至幾千個新聞網站或部落格的文字內容時,一個網站一個網站的建立模板將會是一個非常累人的活兒,維護這麼多模板也是一個辛苦的事情,一旦網站改版,模板就失效,要及時修改模板。

這裡,我將給大家介紹一種通用的演算法來提取這類以文字為主的網頁的文字內容(或者叫正文)。這個演算法的思想其實很簡單,是透過計算文字密度來得到html中包含正文內容的標籤。

我們以猿人學網站的一篇博文網頁為例,來看看這個演算法是如何實現的。

首先,我們先看看一篇博文網頁的結構:

猿人學網頁介面

這篇博文網頁同步是選單欄,左側是一個系列文章的導航選單,右側是相關文章,這些不是我們要的正文內容。正文內容在中間一列。上面截圖沒有把中間這一列截全,它比較長。

再開啟這個網頁的原始碼看看,一眼望去,可以看到純文字的密度還是比較明顯的。

網頁文字密度

這裡,我們要理清幾個概念:

純文字: 指的是html程式碼中,html標籤(tag)外面的字元,這些是在網頁中看到的文字。所以style和JavaScript相關的字元雖然在標籤外面,但也不是純文字。

標籤文字: 是包含在<>之間的部分,截圖中可以看到它們是帶顏色的,而純文字是黑色的。而style和JavaScript不在<>之間但它們不會顯示在網頁中,所以這兩者也是標籤文字。

理解了上面兩個概念,我們再看看網頁原始碼,黑壓壓的部分就是我們要提取的正文部分。而那些花花綠綠的部分是我們不要的選單、相關推薦。

發現這個規律後,我們就可以透過程式碼來找到哪部分html程式碼的“黑壓壓”程度最大,那這部分就是我們要找的正文部分。

具體的演算法如下:

  1. 透過lxml構建網頁的DOM樹
  2. 遍歷DOM數的每個節點,計算該節點及其子節點的文字長度。為什麼要計運算元節點呢?因為一篇文章的正文內容部分通常是一個<div>節點下面包含多個<p>節點,每個<p>節點是一個段落。
  3. 透過排序得到文字長度最長的那個節點,提取該節點的文字內容就得到了這個網頁的正文文字。

這個演算法是不是很簡單,詳細你可以自己實現這個演算法。不過,這個演算法裡面還是有很多tricks的,可能有些細節你不長時間的使用是不會想到的。巧的是,我把這個演算法開源了,你可以從中發現更多的細節。

老規矩,猿人學Python微信公眾號後臺回覆“正文提取”來獲取原始碼。

 

二、建立你自己的搜尋引擎

爬蟲抓了大量的網頁,又從中提取了大量的文字內容。我們拿他們幹嘛用呢?最基本的就是可以做一個搜尋引擎。

比如抓了大量的新聞網頁,我們可以建立一個“新聞搜尋引擎”,就像百度新聞搜尋一樣;

或者,我們抓了大量的技術文章,就可以建立一個“技術搜尋引擎”,如果你能把stackoverflow、github上面的東西也抓下來放到這個“技術搜尋引擎”裡面,那麼你這個搜尋引擎肯定受程式設計師歡迎。

那麼如何做這樣的搜尋引擎呢?可能你已經知道,想Google、百度這樣的搜尋引擎也就三大塊模組:

爬蟲:抓網頁

索引:給網頁建立倒排索引,方便快速搜尋

搜尋:根據搜尋詞去索引裡面找,並根據一定的排序演算法排序結果。

爬蟲我們已經有了,網頁也清洗過了(提取了正文),接下來就是要實現索引和搜尋。

搜尋引擎從Google開始到現在已經二十年了,這方便的技術是很成熟了。同樣的開源工具也有很多工大家學習和使用。這裡,介紹兩個給大家,今後工作學習中如果需要全文搜尋的話,就用它們好了。

(1)Elasticsearch:估計很多人都知道這個工具了,這是開源界使用最廣的搜尋引擎。

(2)Sphinxsearch:這個也是一個非常好的工具,用C++實現,比Java時效性的Elasticsearch要更快。它和MySQL結合的非常好,也就是說,你的資料放在MySQL,它的索引程式會讀取MySQL資料並建立索引。當然,它還支援PostgreSQL等其它資料庫。我使用這個搜尋引擎有十年了,還是很推薦它的。

2017年,Sphinxsearch團隊的一些人出來另立門戶,取名:ManticoreSearch。Sphinx和Manticore都是怪獸的名字,這倆隊伍有點死磕的味道。這之後,Sphinx就不釋出原始碼了,只發布編譯好的二進位制程式;而Manticore再當時sphinx程式碼的基礎上開始了自己開發的過程,同時繼續開源。

我也把搜尋引擎從Sphinx換到了Manticore,並給程式碼加上了中文分詞的支援,並把程式碼放到了我的github上,後來有個人看到了我的程式碼就給Manticore提交了pullrequest。我看到後,Manticore剛釋出了3.0版本,這個版本改動很大,我新增的分詞是2.3版的,對3.0版的程式碼有很大的衝突。於是,我又在3.0版本上加了中文分詞並提交給Manticore。結果他們回覆,他們正在做基於ICU的中文分詞部分,就不merge我的分詞了。目前的情況是,他們已經發布了支援中文分詞的程式碼到github上。我試過最新程式碼,是可以使用的。但是,官方還沒有釋出相關文件,如果你要使用官方的中文分詞部分,先去看看pullrequest裡面我與他們的對話就弄明白了。後面有機會,我寫個使用文件。

 

三、詞雲圖

先感官上認識一下它是個什麼東東:

詞雲圖

上面這樣的圖片就稱為“詞雲圖”,透過詞語的權重來控制文字的大小,來把很多詞彙繪製到一張圖片中。

繪製詞雲圖的目的是直觀瞭解一篇文章或一批文章中哪些話題比較熱門,這是資料視覺化的一種方式。

要繪製這樣一張圖,用Python先進行分詞,統計詞頻,去掉停用詞就會得到一組詞彙及其詞頻,詞頻越大的寫出來的字型也越大。

要畫這個圖,可以用PIL模組,加上中文字型,還要計算圖片哪些地方是空白的等等。這個繪製過程確實比較複雜。但你不用怕,Python已經有現成的庫來完成這件事情,它就是wordcloud,需要的時候用它吧。

 

四、自然語言理解(NLP)

上面統計詞頻時,我們提到了“分詞”,這個技術就是NLP的一部分。“分詞”就是給中文文字中詞彙之間加上空格,我們知道,英文單詞之間是有空格的,而中文詞彙之間沒有分隔符。

NLP是IT技術的一個領域,它試圖讓計算機自動化處理我們人類的語言(自然語言),甚至是理解自然語言。這個領域已經發展了很多很多年,搜尋引擎其實就應用了大量的NLP技術來提高搜尋結果的相關性。

分詞是中文NLP的最基本的技術,基礎的NLP主要包括:

(1)中文分詞

學/ Python/ 上/ 猿人學/ 網站

(2)詞性標註

學/v Python/n 上/v 猿人學/n 網站/n

(3)命名實體識別

學/v Python/n 上/v 猿人學/N 網站/n

(4)句法分析

句法分析

爬蟲抓取過來的檔案資料,可以透過NLP技術做分析。目前,基本的NLP的開源工具也有很多,這裡向大家介紹幾個好用的。

(1)jieba分詞

它使用純Python實現,所以在Windows、Linux上使用都很方便。它的口號是“做最好的 Python 中文分片語件”。除了分詞,它還有“關鍵詞抽取”,可以用來抽取關鍵詞去畫詞雲圖。

(2)LTP:哈工大開源

(3)THUNLP:清華大學開源

這兩個是學院派的工具,用C++實現,封裝為Python模組。使用起來可能要費點事,但是它功能多,除了分詞,詞性標註、命名實體識別、句法分析的功能都有。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章