使用node.js cheerio抓取網頁數據

想要自動從網頁抓一些數據或者想把一坨從什麼博客上拉來的數據轉成一種有結構的數據?javascript

竟然沒有現成的API能夠取數據?!!! !@#$@#$…
不要緊 網頁抓取能夠解決。
什麼是網頁抓取? 你可能會問。。。
網頁抓取是以編程的方式(一般不用瀏覽器參與)檢索網頁的內容並從中提取數據的過程。
 
本文,小編會給你們展現一套強大的抓取工具,能夠快速的對網面進行抓取,並且容易上手,它是由javascript 和node.js實現的。
 
最近我須要爬一些大數量(謙虛的說)的頁面,而後分析它們從中找到一些規律。 你知道,實在太長時間沒有幹過種事了。。。這麼說吧, 手頭基本上是沒有現成的工具能夠用了。。
 
我必須認可我實在太喜歡node.js了。 Node.js是一個用來脫離瀏覽器寫javascript程序的框架。 在 Atwood’s 定律的指引下, node.js有了一套很強大的工具來幫助你們開發網絡程序。你不光能夠用node.js來開發webserver/websocket的代碼, 我發現它還能夠知足我一些平常的腳本須要。 因此我開始尋找node.js在網頁抓取方面的現成庫或工具, 果真,我找到了  Cheerio. Cheerio 是一個Node.js的庫, 它能夠從一坨html的片段中構建DOM結構,而後提供像jquery同樣的css選擇器查詢。
 
太好了! 由於,在這個世界上CSS和CSS驅動的樣式鏈表幾乎是惟一的網頁組織方式。(CSS乾的好!)最近人們每每使用CSS class風格的方式來製做各類結構的網頁。別誤解我,這個並非解決問題的金鑰匙,我依然要處理大量的網頁,大部分是雜亂無章的。 可是對我來講 CSS選擇器提供一個強大快捷而簡單工具,從html中進行有效的的數據識別。 我典型的網頁抓取流程是這樣的, 首先用firebug或chrome開發者工具分析一下目標網頁的結構。主要關注的是我感興趣的數據即目標數據的css選擇器。 接下來就是用node.js搞起了。
 
若是你沒有安裝node.js或者好久沒有升級了, 那麼從 這裏下載。 安裝程序不只會安裝node.js自己,還會裝一個叫作npm的node 工具包管理器,npm能夠用來快速下載並安裝node.js的庫。 這果咱們用npm來安裝Cheerio這個庫。 運行如下這條命令。
 
1
npm install cheerio
 
一旦Cheerio安裝完成, 咱們就能夠開始工做了。 首先讓咱們來看一段javascript代碼 這段代碼能夠下載任意一個網頁的內容。
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var http = require( "http" );
 
// Utility function that downloads a URL and invokes
// callback with the data.
function download(url, callback) {
   http.get(url, function (res) {
     var data = "" ;
     res.on( 'data' , function (chunk) {
       data += chunk;
     });
     res.on( "end" , function () {
       callback(data);
     });
   }).on( "error" , function () {
     callback( null );
   });
}
 這段代碼能夠異步下載任意的URL (經過 HTTP GET方法), 並且在完成下載的時候,它會調用回調函數並把下載的內容當作參數傳進去。接下的一段代碼能夠下載任意一個網頁並將其內容輸出到控制檯。
 
注意: 請你們從 源碼中引用download.js  只要簡單的遠行以下代碼。
 
1
node download.js
讓咱們詳細看一下代碼。
 
1
2
3
4
5
6
7
8
 
download(url, function (data) {
   if (data) {
     console.log(data);
   }
   else console.log( "error" ); 
});
這段代碼會從指定的url下載內容並把內容打印到控制檯。 如今咱們已經有了能夠從網頁下載的內容的方法, 接下來就看Cheerio如何去提取咱們感興趣的數據了。
 
在實際操做前,咱們還要作一點研究和實驗,以幫助咱們理解目標網頁的佈局結構, 這樣就可提取出人感興趣的內容了。 在這個具體的例子裏, 咱們試圖把這些url裏的主要的圖片取出來。 咱們能夠先用瀏覽器打開這些網頁,而後找到一個能夠定位到這些圖片的方法, 你能夠用chrome開發者工具 或直接看源碼(比較難)能夠具體的分離定位這些圖片,明白了麼? 讓咱們來看代碼吧。
注意:  請引用  squirrel.js 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var cheerio = require( "cheerio" );
 
 
download(url, function (data) {
   if (data) {
     //console.log(data);
 
     var $ = cheerio.load(data);
     $( "div.artSplitter > img.blkBorder" ). each ( function (i, e) {
         console.log($(e).attr( "src" ));
       });
 
     console.log( "done" );
   }
   else console.log( "error" ); 
});
引入cheerio模塊後, 咱們能夠用以前寫好的download方法下載目標網頁的內容。 一旦咱們有了數據, cheerio.load方法就會把HTML內容解析成DOM對象 而且能夠像jquery css選擇器查詢那樣對這個DOM進行篩選,(注意:我把這個變量叫作$這樣就更像jquery了)。在目標網頁,我注意到這些圖片所在的div都有一個叫作 「artSplitter」的class, 並且這些圖片自己都有一個叫作」blkBorderf」的class。 爲了能將它們惟一的找到,我寫了一條css選擇器查詢語句
1
$( "div.artSplitter > img.blkBorder" )
這個語句會返回一個圖片對象列表。 而後咱們用each方法遍歷這些圖片而後把每個圖片的src打印出來。效果還不錯。。。 咱們再來看另一個例子, 請引用 echo.js 源碼。
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var cheerio = require( "cheerio" );
 
var url = "http://www.echojs.com/" ;
 
download(url, function (data) {
   if (data) {
     // console.log(data);
     var $ = cheerio.load(data);
     $( "article" ). each ( function (i, e) {
       var link = $(e).find( "h2>a" );
       var poster = $(e).find( "username" ).text();
       console.log(poster+ ": [" +link.html()+ "](" +link.attr( "href" )+ ")" );
     });
   }
});
在這個栗子裏, 目標是echojs.com。 我想把這個網頁上全部文章的連接抓取並以 markdown的格式打印出來。 首先咱們用如下的語句把全部的artical節點都找到
 
1
$( "article" )
而後遍歷全部的節點,找到在h2下的a標籤 用如下的語句
 
1
var link = $(e).find( "h2>a" );
一樣,我能夠用如下語句找到文章做者的名字
1
var poster = $(e).find( "username" ).text();
但願你能從這篇關於node.js和chreerio的文章中獲得一些快樂吧。 請你們移步  Cheerio documentation 獲取列多的信息。
雖然它可能不是適用於全部大型的網頁抓取,但它絕對是一個強大的工具, 尤爲對於咱們前端javascript jquery的開發來講。
 
 
 
 原文地址:
 
 

Jaime Edmondson heats up football fashion with scorching pictorial
transformice The Latest in Window Treatment Stylescss

相關文章
相關標籤/搜索