1. 程式人生 > >使用nodeJS寫一個簡單的小爬蟲

使用nodeJS寫一個簡單的小爬蟲

需要安裝的依賴:

  • requset

使用request向需要爬取的網站發起一個請求,在回撥裡使用body接收資料

我選取百度相簿,作為本次爬取的網站

使用百度搜素二次元萌妹子,然後在位址列裡將URL複製下來

const request = require('request');

const options = {
    method: "GET",
    url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9"
, headers:{ "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" } } //先列印一下,看看是否抓取到了資料 requset(options,(err,res,body)=>{ console.log(err); console.log(res.statusCode); console.log(body); }) 複製程式碼

當看到控制檯輸出一大串資訊後(網頁原始碼),且沒有報錯,statusCode返回200,說明正確請求到了資料。

接著,我們需要對資料,進行處理(對返回的資料,進行分析,拿到我們想要的資料,這裡我們想要得到資料是圖片的URL地址)。

處理資料的方式:

  • 正則表示式

作為一個程式設計師,處理字串,首先想到的當然是正則了

使用正則去匹配data-url

const request = require('request');

const options = {
    method: "GET",
    url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9"
, headers:{ "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" } } //先列印一下,看看是否抓取到了資料 request(options,(err,res,body)=>{ const reg = /thumbURL":"https?:\/\/.+?&gp=0.jpg/ig; const urlArr = body.match(reg); const msgArr = []; urlArr.forEach(( val,idx ) => { const reg = /https?:\/\/.+?&gp=0.jpg/; msgArr.push(val.match(reg)[0]); }) console.log(msgArr); }) 複製程式碼

匹配成功!!! 我們試著點選一下,能否訪問

就很棒,抓到的資料,沒有問題

接著,我們嘗試著將圖片下載下來

//想要下載圖片,就必須請求圖片的地址
//訪問到圖片的靜態資源後,使用管道流儲存到檔案中
//因為I/O操作是非同步的,所以使用Promise將程式碼改寫一下
const request = require('request');
const fs = require('fs');//寫入檔案,需要匯入fs模組
const options = {
    method: "GET",
    url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9",
    headers:{
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    }
}

new Promise(( res,rej ) => {
    request(options,( err,response,body ) => {
        const reg = /thumbURL":"https?:\/\/.+?&gp=0.jpg/ig;
        const urlArr = body.match(reg);
        const msgArr = [];
        urlArr.forEach(( val,idx ) => {
            const reg = /https?:\/\/.+?&gp=0.jpg/;
            msgArr.push(val.match(reg)[0]);
        })
        res(msgArr);
    })
}).then( msgArr => {
    msgArr.forEach(( val,idx ) => {
        request(val).pipe(fs.createWriteStream("./img/"+idx+".jpg"));
    })
})

複製程式碼

此時開啟資料夾,可以看到圖片已經下載成功!

使用正則,可以解析使用JS渲染的頁面,如果發起請求後,body接收的資料返回的是一個頁面結構,則可以使用以下兩個npm包:

  • jsdom
  • cheerio

jsdom可以將資料解析成DOM結構,cheerio則將資料包裝成jQuery

以百度搜索為例,如果要抓取搜尋結果的標題內容和連結

//
const request = require("request")
const {JSDOM} = require("jsdom")
//const cheerio = require("cheerio")

const word = encodeURI("二次元萌妹")
request({
    url : "https://www.baidu.com/s?wd="+word,
    headers:{
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    }
},(err,response,body)=>{
    if(err)throw err;
    if( response.statusCode >=200 && response.statusCode<300 ){
        //JSDOM處理body
        let {window} = new JSDOM(body);
        let aDOM = window.document.querySelectorAll("h3.t a");
        [...aDOM].forEach(ele => {
            console.log(ele.text,ele.href);
        })

        //cheerio處理body
        /*let $ = cheerio.load(body);
        $("h3.t a").each((i,ele)=>{
            console.log($(ele).attr("href"));
            console.log($(ele).text());
        })*/
    }
});

複製程式碼

得到的結果

可以看到操作十分簡便,但是如果資料量大,這種方法效能不佳