node.js 爬蟲入門總結

node.js爬蟲

前端同學可能向來對爬蟲不是很感冒,覺得爬蟲需要用偏后端的語言,諸如 php , python 等。當然這是在 nodejs 前了,nodejs 的出現,使得 Javascript 也可以用來寫爬蟲了。由于 nodejs 強大的異步特性,讓我們可以輕松以異步高并發去爬取網站,當然這里的輕松指的是 cpu 的開銷。

要讀懂本文,其實只需要有

  • 能看懂 Javascript 及 JQuery
  • 簡單的nodejs基礎
  • http 網絡抓包 和 URL 基礎

Nodejs做爬蟲的優劣

首先說一下node做爬蟲的優勢

第一個就是他的驅動語言是JavaScript。JavaScript在nodejs誕生之前是運行在瀏覽器上的腳本語言,其優勢就是對網頁上的dom元素進行操作,在網頁操作上這是別的語言無法比擬的。

第二就是nodejs是單線程異步的。聽起來很奇怪,單線程怎么能夠異步呢?想一下學操作系統的時候,單核cpu為什么能夠進行多任務處理?道理也是類似,在操作系統中進程對CPU的占有進行時間切片,每一個進程占有的時間很短,但是所有進程循環很多次,因此看起就像是多個任務在同時處理。js也是一樣,js里有事件池,CPU會在事件池循環處理已經響應的事件,未處理完的事件不會放到事件池里,因此不會阻塞后續的操作。在爬蟲上這樣的優勢就是在并發爬取頁面上,一個頁面未返回不會阻塞后面的頁面繼續加載,要做到這個不用像python那樣需要多線程。

其次是node的劣勢

首先是異步并發上。處理的好很方便,處理的不好就會很麻煩。例如要爬取10個頁面,用node不做異步處理話,那返回的結果可不一定是按1、2、3、4……這個順序,很可能是隨機。解決的辦法就是增加一個頁面的序列戳,讓爬取的數據生成csv文件,然后重新排序。

第二個是數據處理上的劣勢,這點是不如python的,如果只是單純的爬數據,用node當然很好,但是如果用爬來的數據繼續做統計分析,做個回歸分析聚類啥的話,那就不能用node一步到底了。

如何用nodejs做爬蟲

下面就要說一下如何用nodejs做爬蟲了

  • 1、初始化項目文件

在對應的項目文件夾下執行npm init來初始化一個package.json文件

  • 2、安裝request和cheerio依賴包

request聽起來很熟悉吧,跟python里request功能一樣。它的功能就是建立起對目標網頁的鏈接,并返回相應的數據,這個不難理解。

cheerio的功能是用來操作dom元素的,他可以把request返回來的數據轉換成可供dom操作的數據,更重要的cheerio的api跟jquery一樣,用$來選取對應的dom結點,是不很方便?對一個前端程序員來說,這比python的什么xpath和beautisoup方便了不知道多少啊哈哈

安裝命令也很簡單:

分別是npm install request --save 和 npm install cheerio

  • 3、引入依賴包并使用

接下來就用request , fs和cherrio寫一個爬蟲吧!

首先引入依賴模塊

var http=require("http");        //網絡請求var fs=require("fs");            //操作文件,讀寫文件var cheerio=require("cheerio");  //擴展模塊注:cheerio 模塊是第三方模塊,需要進行安裝:npm install cheerio --save

接下來就以我之前爬取的的百度新聞頁為例吧,為什么要選這個呢,因為這個是最基礎最簡單的。

百度新聞頁面鏈接是:http://news.baidu.com/

執行下面代碼:

var http=require("http");
var fs=require("fs");const wz="http://news.baidu.com/"; //網址var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){console.log(strHtml);});
})

運行一下結果就是這樣的

圖片描述

是不是很激動哈哈,html返回回來了。這樣還是不夠的,接下就是要處理下返回的數據,并提煉出我們想要獲得的信息,這就輪到cheerio登場了

將request返回的結果傳入cheerio中,并獲得想要獲取的信息,看代碼是不是想在寫腳本的感覺?

接下來我們在獲取一下這一段

圖片描述

執行以下代碼:

var http=require("http");var fs=require("fs");var cheerio=require("cheerio");const wz="http://news.baidu.com/";var strHtml="";
var results=[];
http.get(wz,function(res){res.on("data",function(chunk){strHtml+=chunk;})res.on("end",function(){//console.log(strHtml);var $=cheerio.load(strHtml);$("#channel-all li").each((iten,i)=>{console.log($(i).text());})});
})        

運行一下結果如下:

圖片描述

這樣一個簡單的爬蟲就完成啦,是不是很簡單啊。

然后再簡單的介紹一下node.js爬取圖片

以下是我們將要爬取的圖片:

圖片描述

首先我們也需要同上面一樣引入一些需要的核心模塊

var http = require("http");var https = require("https");var fs = require("fs");var cheerio = require("cheerio");

注:cheerio 模塊是第三方模塊,需要進行安裝:

npm install cheerio --save

//保存網絡圖片
function saveImage(imageUrl){http.get(imageUrl, function (res) {res.setEncoding('binary');      //二進制(binary)var imageData ='';res.on('data',function(data){  //圖片加載到內存變量imageData += data;}).on('end',function(){        //加載完畢保存圖片if(!fs.existsSync("./images")){fs.mkdirSync("./images");}fs.writeFile('images/'+Math.random()+'.png',imageData,'binary',function (err) {  //以二進制格式保存if(err) throw err;console.log('保存成功');});});});
}

圖片描述

nodejs 爬蟲總結

① http.get+cheerio+iconv-lite

這種方式還是比較簡單的,容易理解,直接使用http的get方法進行請求url,將得到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。

要點:

得到的結果中文亂碼如何解決呢,用iconv-lite模塊將得到的內容進行轉碼即可。

http.get(options,function(result){var body = [];result.on('data',function(chunk){body.push(chunk);});result.on('end', function () {var html = iconv.decode(Buffer.concat(body), 'gb2312');  //注意這里body是數組var $ = cheerio.load(html);...});
});

② request+cheerio+iconv-lite

這種方式在獲取內容的方式上與上有些不同,可以直接獲取到Buffer類型的數據。然后將得到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。

要點:

結果中文亂碼如何解決,用iconv-lite模塊將得到的內容進行轉碼即可。

request(options,function(err,res,body){if(err)console.log(err);if(!err&&res.statusCode==200){var html = iconv.decode(body, 'gb2312');     //這里body是直接拿到的是Buffer類型的數據,可以直接解碼。var $ = cheerio.load(html);...}
});

③ superagent+cheerio+superagent-charset

這種方式是比前面兩個有較大差別,用了superagent的get方法發起請求,解碼的時候用到了superagent-charse,用法還是很簡單的,之后再將獲取到的內容給cheerio解析,用jquery的方式解析出我們要東西即可。

要點:

結果中文亂碼解決用superagent-charset模塊進行轉碼,方式較之上面有點差別。

首先看它的加載方式:

var charset = require("superagent-charset");var superagent = charset(require("superagent"));   //將superagent模塊傳遞給superagent-charset

解碼方式:

superagent.get(url).charset('gb2312')                                //用charset方法達到解碼效果。.end(function(err,result){if(err) console.log(err);var $ = cheerio.load(result.text);...});

至此呢,Nodejs爬蟲的核心就已經介紹完畢了,剩下就完全可以自由發揮了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540477.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540477.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540477.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數組重復次數最多的元素遞歸_使用遞歸計算鏈接列表中元素的出現次數

數組重復次數最多的元素遞歸Solution: 解: Required function: 所需功能: func_occurence ( node *temp) //recursive functionInput: 輸入: A singly linked list whose address of the first node is stored in a pointer, say head and…

SecureCRT中文亂碼解決方法

服務端export LANGzh_CN.UTF-8客戶端SecureCRT編碼選擇UTF-8客戶端SecureCRT字體選擇新宋體,字符集選擇中文總結:客戶端和服務端字符編碼一致,客戶端字體字符集支持轉載于:https://blog.51cto.com/leomars/1972669

[轉載] Python 迭代器 深入理解 與應用示例

參考鏈接: Python | 可迭代和迭代器之間的區別 本篇文章簡單談談可迭代對象,迭代器和生成器之間的關系。 三者簡要關系圖 可迭代對象與迭代器 剛開始我認為這兩者是等同的,但后來發現并不是這樣;下面直接拋出結論: 1…

Python程序查找表示O(1)復雜度的數字所需的位數

Problem statement 問題陳述 Find total Number of bits required to represent a number in binary 查找以二進制表示數字所需的總位數 Example 1: 范例1: input : 10output: 4Example 2: 范例2: input : 32output : 6Formula used: 使用的公式&am…

正則split

string content "第1行導入失敗,失敗原因為: 《加班原因》字段必填";string[] resultString Regex.Split(content, "失敗原因為:", RegexOptions.IgnoreCase);foreach (string i in resultString){Console.WriteLine(i…

將八進制數制轉換為二進制,十進制和十六進制數制

1)將八進制數制轉換為二進制數制 (1) Conversion of Octal Number System to Binary Number System) To convert octal numbers into binary numbers, we can use the relationship between octal and binary numbers. 要將八進制數轉換為二進制數,我們可以使用八進…

[轉載] Python的生成器

參考鏈接: Python中的生成器Generator Python的生成器 什么是生成器 創建python迭代器的過程雖然強大,但是很多時候使用不方便。生成器是一個簡單的方式來完成迭代。簡單來說,Python的生成器是一個返回可以迭代對象的函數。 怎樣創建生…

想提高用戶訪問的響應速度和成功率還不趕快學習CDN

2019獨角獸企業重金招聘Python工程師標準>>> 課程介紹 CDN可以將源站內容分發至最接近用戶的節點,使用戶可就近取得所需內容,提高用戶訪問的響應速度和成功率。解決因分布、帶寬、服務器性能帶來的訪問延遲問題,適用于站點加速、點…

[轉載] python迭代器、生成器和裝飾器

參考鏈接: 有效地在Python中使用迭代 文章目錄 生成器生成器表達式(generator expression)通過使用yield關鍵字定義生成器并行前戲高潮 迭代器迭代器概述iter()函數 創建迭代器創建一個迭代器(類)內置迭代器工具count無限迭代器cycle 無限迭代器,從一個…

java中的starts_Java Math類靜態double nextAfter(double starts,double direction)示例

java中的starts數學類靜態double nextAfter(雙向啟動,雙向) (Math Class static double nextAfter(double starts , double directions) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the double …

Python 核心編程(第二版)——條件和循環

Python 中的 if 子句由三部分組成: 關鍵字本身,用于判斷結果真假的條件表達式, 以及當表達式為真或者非零時執行的代碼塊。if 語句的語法如下: if expression: expr_true_suite 單個 if 語句可以通過使用布爾操作符 and , or 和 not實現多重判斷條件或…

[轉載] 【python魔術方法】迭代器(__iter__和__next__)

參考鏈接: Python __iter __()和__next __()| 將對象轉換為迭代器 文章目錄 __iter__ 和 __next__真正的迭代器總結 python里面有很多的以__開始和結尾的函數,利用它們可以完成很多復雜的邏輯代碼,而且提高了代碼的簡潔性,本文主…

Silverlight 異步單元測試

Silverlight 中的很多操作都是異步的,很多情況下要求單元測試也是異步的,但是介紹異步單元測試的文檔很少。通過對 Silverlight Toolkit 中的 Microsoft.Silverlight.Testing 和 Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight 這兩個文件…

網絡拓撲 令牌環網 以太網_以太網連接中網絡拓撲的類型及其框架 以太網技術...

網絡拓撲 令牌環網 以太網A topology explains how physically the network is designed or what is the structure of the network. These designs are both physical and logical. There are many network topologies 4 like Bus, Star, Ring, and Mesh. But only two types …

Wafer晶圓封裝工藝介紹

芯片封裝的目的(The purpose of chip packaging): 芯片上的IC管芯被切割以進行管芯間連接,通過引線鍵合連接外部引腳,然后進行成型,以保護電子封裝器件免受環境污染(水分、溫度、污染物等)&…

[轉載] Python中的解析式和生成器表達式

參考鏈接: Python | 生成器表達式 解析式和生成器表達式 列表解析List Comprehension 語法 [返回值 for 元素 in 可迭代對象 if 條件]使用中括號[],內部是for循環,if條件語句可選,會返回一個新的列表 列表解析試優點 編譯器會優化&…

java 數字字母進位_使用帶有進位的8085微處理器將兩個8位數字相乘

java 數字字母進位Problem statement: 問題陳述: Multiplication of two 8 bits numbers using 8085 microprocessor with carry. 使用帶有進位的8085微處理器將兩個8位數字相乘。 Algorithm: 算法: Load HL pair with initial data using LHLD comma…

[轉載] Python3.0中普通方法、類方法和靜態方法的比較

參考鏈接: Python中的類方法與靜態方法 一、語法區別 剛接觸Python中的面向對象,對于類方法和靜態方法難以區分,通過查找知乎、CSDN論壇,廢了好大的勁思路才逐漸明朗,所以就總結順便分享一下。 首先開始編輯代碼 # 普…

iOS:個人淺談工廠模式

一、什么是工廠方法? 正式的解釋是:在基類中定義創建對象的一個接口,讓子類決定實例化哪個類。工廠方法讓一個類的實例化延遲到子類中進行。工廠方法要解決的問題是對象的創建時機,它提供了一種擴展的策略,很好地符合了…

scanf 輸入十六進制_使用C語言中的scanf()在字符變量中輸入十進制,八進制和十六進制值...

scanf 輸入十六進制Here, we will declare an unsigned char variable and input different formats value like decimal format, octal format and hexadecimal format. 在這里,我們將聲明一個無符號的char變量,并輸入不同格式的值,例如十進…