首頁 web前端 js教程 使用NodeJS編寫爬蟲範例

使用NodeJS編寫爬蟲範例

Jun 20, 2018 pm 04:29 PM
nodejs

這篇文章主要跟大家講解了一下用NodeJS學習爬蟲,並透過爬糗事百科來講解用法和效果,一起學習下吧。

1.前言分析

平常都是利用Python/.NET 語言實作爬蟲,原本現在作為前端開發人員,自然需熟練NodeJS。下面利用 NodeJS 語言實作一個糗事百科的爬蟲。另外,本文使用的部分程式碼是 es6 語法。

實作該爬蟲所需的依賴函式庫如下。

request: 利用 get 或 post 等方法取得網頁的原始碼。 cheerio: 網頁原始碼解析,取得所需資料。

本文首先對爬蟲所需依賴函式庫及其使用進行介紹,然後利用這些依賴函式庫,實作一個針對糗事百科的網路爬蟲。

2. request 函式庫

request 是一個輕量級的 http 函式庫,功能十分強大且使用簡單。可以使用它實作 Http 的請求,並且支援 HTTP 認證, 自定請求頭等。以下對 request 庫中一部分功能進行介紹。

安裝 request 模組如下:

npm install request
登入後複製

在安裝好 request 後,即可進行使用,下面利用 request 請求一下百度的網頁。

const req = require('request');
req('http://www.baidu.com', (error, response, body) => {
 if (!error && response.statusCode == 200) {
 console.log(body)
 }
})
登入後複製

在沒有設定 options 參數時,request 方法預設是 get 請求。而我喜歡利用 request 物件的具體方法,使用如下:

req.get({
 url: 'http://www.baidu.com'
},(err, res, body) => {
 if (!err && res.statusCode == 200) {
 console.log(body)
 }
});
登入後複製

然而很多時候,直接去請求一個網址所獲取的 html 源碼,往往得不到我們需要的資訊。一般情況下,需要考慮到請求頭和網頁編碼。

網頁的請求頭網頁的編碼

下面介紹在請求的時候如何添加網頁請求頭以及設定正確的編碼。

req.get({
 url : url,
 headers: {
  "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
  "Host" : "www.zhihu.com",
  "Upgrade-Insecure-Requests" : "1"
 },
 encoding : 'utf-8'
}, (err, res, body)=>{
 if(!err)
  console.log(body);
})
登入後複製

設定 options 參數, 新增 headers 屬性即可實現請求頭的設定;新增 encoding 屬性即可設定網頁的編碼。需要注意的是,若 encoding:null ,那麼 get 請求所取得的內容則是 Buffer 對象,即 body 是一個 Buffer 物件。

上面介紹的功能足矣滿足後面的所需了

#3. cheerio 庫

cheerio 是一款伺服器端的Jquery,以輕、快、簡單易學等特色被開發者喜愛。有 Jquery 的基礎後再來學習 cheerio 函式庫非常輕鬆。它能夠快速定位到網頁中的元素,其規則和 Jquery 定位元素的方法是一樣的;它也能以一種非常方便的形式修改 html 中的元素內容,以及獲取它們的資料。以下主要針對 cheerio 快速定位網頁中的元素,以及取得它們的內容進行介紹。

先安裝 cheerio 函式庫

npm install cheerio
登入後複製

下面先給一段程式碼,再對程式碼進行解釋 cheerio 函式庫的用法。對部落格園首頁進行分析,然後提取每一頁中文章的標題。

首先對部落格園區首頁進行分析。如下圖:

對html 原始碼進行分析後,首先透過.post_item 取得所有標題,接著對每一個.post_item 進行分析,使用a.titlelnk 即可符合每個標題的a 標籤。下面透過程式碼進行實作。

const req = require('request');
const cheerio = require('cheerio');

req.get({
 url: 'https://www.cnblogs.com/'
 }, (err, res, body) => {
 if (!err && res.statusCode == 200) {
  let cnblogHtmlStr = body;
  let $ = cheerio.load(cnblogHtmlStr);
  $('.post_item').each((index, ele) => {
  let title = $(ele).find('a.titlelnk');
  let titleText = title.text();
  let titletUrl = title.attr('href');
  console.log(titleText, titletUrl);
  });
 }
 });
登入後複製

當然,cheerio 函式庫也支援鍊式調用,上面的程式碼也可改寫成:

let cnblogHtmlStr = body;
let $ = cheerio.load(cnblogHtmlStr);
let titles = $('.post_item').find('a.titlelnk');
titles.each((index, ele) => {
 let titleText = $(ele).text();
 let titletUrl = $(ele).attr('href');
 console.log(titleText, titletUrl);
登入後複製

上面的程式碼非常簡單,就不再用文字進行贅述了。以下總結一點自己認為比較重要的幾點。

使用find() 方法取得的節點集合A,若再次以A 集合中的元素為根節點定位它的子節點以及取得子元素的內容與屬性,需對A 集合中的子元素進行$(A[i]) 包裝,如上面的$(ele) 一樣。在上面程式碼中使用$(ele) ,其實還可以使用$(this) 但是由於我使用的是es6 的箭頭函數,因此改變了each 方法中回調函數的this 指針,因此,我使用$(ele); cheerio 庫也支援鍊式調用,如上面的$('.post_item').find('a .titlelnk') ,需要注意的是,cheerio 物​​件A 呼叫方法find(),如果A 是集合,那麼A 集合中的每一個子元素都會呼叫find( ) 方法,並放回一個結果結合。如果A 呼叫text() ,那麼A 集合中的每一個子元素都會呼叫text() 並傳回一個字串,該字串是所有子元素內容的合併(直接合併,沒有分隔符號)。

最後在總結一些我比較常用的方法。

first() last() children([selector]): 這個方法和 find 類似,只不過此方法只搜尋子節點,而 find 搜尋整個後代節點。

4. 糗事百科爬蟲

#

通过上面对 requestcheerio 类库的介绍,下面利用这两个类库对糗事百科的页面进行爬取。

1、在项目目录中,新建 httpHelper.js 文件,通过 url 获取糗事百科的网页源码,代码如下:

//爬虫
const req = require('request');

function getHtml(url){
 return new Promise((resolve, reject) => {
  req.get({
   url : url,
   headers: {
    "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    "Referer" : "https://www.qiushibaike.com/"
   },
   encoding : 'utf-8'
  }, (err, res, body)=>{
   if(err) reject(err);
   else resolve(body);
  })
 });
}
exports.getHtml = getHtml;
登入後複製

2、在项目目录中,新建一个 Splider.js 文件,分析糗事百科的网页代码,提取自己需要的信息,并且建立一个逻辑通过更改 url 的 id 来爬取不同页面的数据。

const cheerio = require('cheerio');
const httpHelper = require('./httpHelper');
function getQBJok(htmlStr){
 let $ = cheerio.load(htmlStr);
 let jokList = $('#content-left').children('p');
 let rst = [];
 jokList.each((i, item)=>{
  let node = $(item);
  let titleNode = node.find('h2');
  let title = titleNode ? titleNode.text().trim() : '匿名用户';
  let content = node.find('.content span').text().trim();
  let likeNumber = node.find('i[class=number]').text().trim();
  rst.push({
   title : title,
   content : content,
   likeNumber : likeNumber
  });
 });
 return rst;
}
async function splider(index = 1){
 let url = `https://www.qiushibaike.com/8hr/page/${index}/`;
 let htmlStr = await httpHelper.getHtml(url);
 let rst = getQBJok(htmlStr);
 return rst;
}
splider(1);
登入後複製

在获取糗事百科网页信息的时候,首先在浏览器中对源码进行分析,定位到自己所需要标签,然后提取标签的文本或者属性值,这样就完成了网页的解析。

Splider.js 文件入口是 splider 方法,首先根据传入该方法的 index 索引,构造糗事百科的 url,接着获取该 url 的网页源码,最后将获取的源码传入 getQBJok 方法,进行解析,本文只解析每条文本笑话的作者、内容以及喜欢个数。

直接运行 Splider.js 文件,即可爬取第一页的笑话信息。然后可以更改 splider 方法的参数,实现抓取不同页面的信息。

在上面已有代码的基础上,使用 koavue2.0 搭建一个浏览文本的页面,效果如下:

源码已上传到 github 上。下载地址:https://github.com/StartAction/SpliderQB ;

项目运行依赖 node v7.6.0 以上, 首先从 Github 上面克隆整个项目。

git clone https://github.com/StartAction/SpliderQB.git
登入後複製

克隆之后,进入项目目录,运行下面命令即可。

node app.js
登入後複製

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在jQuery中如何获取数据赋值给页面

在jquery中如何实现左右轮播切换

使用jquery如何实现楼层滚动效果

使用jquery如何实现定位式导航

利用jquery.page.js如何实现分页效果

以上是使用NodeJS編寫爬蟲範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

nodejs和vuejs區別 nodejs和vuejs區別 Apr 21, 2024 am 04:17 AM

Node.js 是一種伺服器端 JavaScript 執行時,而 Vue.js 是一個客戶端 JavaScript 框架,用於建立互動式使用者介面。 Node.js 用於伺服器端開發,如後端服務 API 開發和資料處理,而 Vue.js 用於用戶端開發,如單一頁面應用程式和響應式使用者介面。

nodejs是後端框架嗎 nodejs是後端框架嗎 Apr 21, 2024 am 05:09 AM

Node.js 可作為後端框架使用,因為它提供高效能、可擴展性、跨平台支援、豐富的生態系統和易於開發等功能。

nodejs怎麼連接mysql資料庫 nodejs怎麼連接mysql資料庫 Apr 21, 2024 am 06:13 AM

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 Apr 21, 2024 am 05:18 AM

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

nodejs中的全域變數有哪些 nodejs中的全域變數有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

nodejs和java的差別大嗎 nodejs和java的差別大嗎 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

nodejs是後端開發語言嗎 nodejs是後端開發語言嗎 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一種後端開發語言。它用於後端開發,包括處理伺服器端業務邏輯、管理資料庫連接和提供 API。

nodejs專案怎麼部署到伺服器 nodejs專案怎麼部署到伺服器 Apr 21, 2024 am 04:40 AM

Node.js 專案的伺服器部署步驟:準備部署環境:取得伺服器存取權限、安裝 Node.js、設定 Git 儲存庫。建置應用程式:使用 npm run build 產生可部署程式碼和相依性。上傳程式碼到伺服器:透過 Git 或檔案傳輸協定。安裝依賴項:SSH 登入伺服器並使用 npm install 安裝應用程式相依性。啟動應用程式:使用 node index.js 等命令啟動應用程序,或使用 pm2 等進程管理器。設定反向代理(可選):使用 Nginx 或 Apache 等反向代理路由流量到應用程式

See all articles