NO IMAGE

關於爬蟲內容的分享,我會分成兩篇,六個部分來分享,分別是:

  1. 我們的目的是什麼
  2. 內容從何而來
  3. 瞭解網路請求
  4. 一些常見的限制方式
  5. 嘗試解決問題的思路
  6. 效率問題的取捨

本文先聊聊前三個部分。

一、我們的目的是什麼

一般來講對我們而言需要抓取的是某個網站或者某個應用的內容,提取有用的價值,內容一般分為兩部分,非結構化的文字,或者結構化的文字。

關於非結構化的資料

1.1 HTML文字(包含javascript程式碼)

HTML文字基本上是傳統爬蟲過程中最常見的,也就是大多數時候會遇到的情況,例如抓取一個網頁,得到的是HTML,然後需要解析一些常見的元素,提取一些關鍵的資訊。HTML其實理應屬於結構化的文字組織,但是又因為一般我們需要的關鍵資訊並非直接可以得到,需要進行對HTML的解析查詢,甚至一些字串操作才能得到,所以還是歸類於非結構化的資料處理中。

常見解析方式如下:

CSS選擇器

現在的網頁樣式比較多,所以一般的網頁都會有一些CSS的定位,例如class,id等等,或者我們根據常見的節點路徑進行定位,例如騰訊首頁的財經部分:

這裡id就為finance,我們用css選擇器,就是’#finance’就得到了財經這一塊區域的html,同理,可以根據特定的css選擇器可以獲取其他的內容。

XPATH

XPATH是一種頁面元素的路徑選擇方法,利用chrome可以快速得到,如:

一看就明白的爬蟲入門講解-基礎理論篇

copy XPATH 就能得到——//*[@id=’finance’]

正規表示式

正規表示式,用標準正則解析,一般會把HTML當做普通文字,用指定格式匹配當相關文字,適合小片段文字,或者某一串字元,或者HTML包含javascript的程式碼,無法用CSS選擇器或者XPATH。

字串分隔

同正規表示式,更為偷懶的方法,不建議使用。

1.2 一段文字

例如一篇文章,或者一句話,我們的初衷是提取有效資訊,所以如果是滯後處理,可以直接儲存,如果是需要實時提取有用資訊,常見的處理方式如下:

分詞

根據抓取的網站型別,使用不同詞庫,進行基本的分詞,然後變成詞頻統計,類似於向量的表示,詞為方向,詞頻為長度。

NLP

自然語言處理,進行語義分析,用結果表示,例如正負面等。

關於結構化的資料

結構化的資料是最好處理,一般都是類似JSON格式的字串,直接解析JSON資料就可以了,提取JSON的關鍵欄位即可

二、內容從何而來

過去我們常需要獲取的內容主要來源於網頁,一般來講,我們決定進行抓取的時候,都是網頁上可看到的內容,但是隨著這幾年移動網際網路的發展,我們也發現越來越多的內容會來源於移動app,所以爬蟲就不止侷限於一定要抓取解析網頁,還有就是模擬移動app的網路請求進行抓取,所以這一部分我會分兩部分進行說明。

1 網頁內容

網頁內容一般就是指我們最終在網頁上看到的內容,但是這個過程其實並不是網頁的程式碼裡面直接包含內容這麼簡單,所以對於很多新人而言,會遇到很多問題,比如:

明明在頁面用Chrome或者Firefox進行審查元素時能看到某個HTML標籤下包含內容,但是抓取的時候為空。

很多內容一定要在頁面上點選某個按鈕或者進行某個互動操作才能顯示出來。

所以對於很多新人的做法是用某個語言別人模擬瀏覽器操作的庫,其實就是呼叫本地瀏覽器或者是包含了一些執行javascript的引擎來進行模擬操作抓取資料,但是這種做法顯然對於想要大量抓取資料的情況下是效率非常低下,並且對於技術人員本身而言也相當於在用一個盒子,那麼對於這些內容到底是怎麼顯示在網頁上的呢?主要分為以下幾種情況:

網頁包含內容

這種情況是最容易解決的,一般來講基本上是靜態網頁已經寫死的內容,或者動態網頁,採用模板渲染,瀏覽器獲取到HTML的時候已經是包含所有的關鍵資訊,所以直接在網頁上看到的內容都可以通過特定的HTML標籤得到

javascript程式碼載入內容

這種情況是由於雖然網頁顯示時,內容在HTML標籤裡面,但是其實是由於執行js程式碼加到標籤裡面的,所以這個時候內容在js程式碼裡面的,而js的執行是在瀏覽器端的操作,所以用程式去請求網頁地址的時候,得到的response是網頁程式碼和js的程式碼,所以自己在瀏覽器端能看到內容,解析時由於js未執行,肯定找到指定HTML標籤下內容肯定為空,這個時候的處理辦法,一般來講主要是要找到包含內容的js程式碼串,然後通過正規表示式獲得相應的內容,而不是解析HTML標籤。

Ajax非同步請求

這種情況是現在很常見的,尤其是在內容以分頁形式顯示在網頁上,並且頁面無重新整理,或者是對網頁進行某個互動操作後,得到內容。那我們該如何分析這些請求呢?這裡我以Chrome的操作為例,進行說明:

一看就明白的爬蟲入門講解-基礎理論篇

所以當我們開始重新整理頁面的時候就要開始跟蹤所有的請求,觀察資料到底是在哪一步載入進來的。然後當我們找到核心的非同步請求的時候,就只用抓取這個非同步請求就可以了,如果原始網頁沒有任何有用資訊,也沒必要去抓取原始網頁了。

2 App內容

因為現在移動應用越來越多,很多有用資訊都在App裡面,另外解析非結構化文字和結構文字對比而言,結構化文字會簡單多了,不同去找內容,去過多分析解析,所有既有網站又有App的話,推薦抓取App,大多數情況下基本上只是一些JSON資料的API了。那麼App的資料該如何抓取呢?通用的方法就是抓包,基本的做法就是電腦安裝抓包軟體,配置好埠,然後記下ip,手機端和電腦在同一個區域網裡面,然後在手機的網路連線裡面設定好代理,這個時候開啟App進行一些操作,如果有網路資料請求,則都會被抓包軟體記下,就如上Chrome分析網路請求一樣,你可以看到所有的請求情況,可以模擬請求操作。這裡Mac上我推薦軟體Charles,Windows推薦Fiddler2。

具體如何使用,之後我再做詳述,可能會涉及到HTTPS證書的問題。

三、瞭解網路請求

剛剛一直在寬泛的提到一些我們需要找到請求,進行請求,對於請求只是一筆帶過,但請求是很重要的一部分,包括如何繞過限制,如何傳送正確地資料,都需要對的請求,這裡就要詳細的展開說下請求,以及如何模擬請求。

我們常說爬蟲其實就是一堆的HTTP請求,找到待爬取的連結,不管是網頁連結還是App抓包得到的API連結,然後傳送一個請求包,得到一個返回包(也有HTTP長連線,或者Streaming的情況,這裡不考慮),所以核心的幾個要素就是:

  1. URL
  2. 請求方法(POST, GET)
  3. 請求包headers
  4. 請求包內容
  5. 返回包headers

在用Chrome進行網路請求捕獲或者用抓包工具分析請求時,最重要的是弄清楚URL,請求方法,然後headers裡面的欄位,大多數出問題就出在headers裡面,最常限制的幾個欄位就是User-Agent, Referer,Cookie 另外Base Auth也是在headers裡面加了Autheration的欄位。

請求內容也就是post時需要傳送的資料,一般都是將Key-Value進行urlencode返回包headers大多數會被人忽視,可能只得到內容就可以了,但是其實很多時候,很多人會發現明明url,請求方法還有請求包的內容都對了,為什麼沒有返回內容,或者發現請求被限制,其實這裡大概有兩個原因:

  • 一個是返回包的內容是空的,但是在返回包的headers的欄位裡面有個Location,這個Location欄位就是告訴瀏覽器重定向,所以有時候程式碼沒有自動跟蹤,自然就沒有內容了;
  • 另外一個就是很多人會頭疼的Cookie問題,簡單說就是瀏覽器為什麼知道你的請求合法的,例如已登入等等,其實就是可能你之前某個請求的返回包的headers裡面有個欄位叫Set-Cookie,Cookie存在本地,一旦設定後,除非過期,一般都會自動加在請求欄位上,所以Set-Cookie裡面的內容就會告訴瀏覽器存多久,存的是什麼內容,在哪個路徑下有用,Cookie都是在指定域下,一般都不跨域,域就是你請求的連結host。

所以分析請求時,一定要注意前四個,在模擬時保持一致,同時觀察第五個返回時是不是有限制或者有重定向。