欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node爬取大批量文件的方法示例

 更新時間:2019年06月28日 08:26:31   作者:hn-failte  
這篇文章主要介紹了Node爬取大批量文件的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

有個朋友在搞留學(xué)工作室,經(jīng)常訪問的一個網(wǎng)站叫留學(xué)者指南,然而每次都要去訪問該網(wǎng)站,顯得極其不專業(yè)。于是托俺幫忙寫腳本去爬他家的東西,我觀察了下,這次,我們要爬的東西就有點多了——大概就20多萬個文件吧~~~

在20多萬個文件中,下載極有可能會被中斷,因此需要做下載進度備份,下載進度恢復(fù)。

那么針對這樣子的需求,我們開始吧!

上代碼!

const cheerio = require("cheerio"); //用于處于HTML文檔流,用法類似jQuery
const http = require("http"); //用于發(fā)起請求
const fs = require("fs"); //用于檢測、寫入文件等其他文件操作

// "http://www.compassedu.hk/sitemap1.txt",
// "http://www.compassedu.hk/sitemap2.txt", //重復(fù)的鏈接
var source = [ //Robots.txt顯示的數(shù)據(jù)源
  "http://m.compassedu.hk/sitemap3.txt",
  "http://m.compassedu.hk/sitemap4.txt",
  "http://m.compassedu.hk/sitemap6.txt",
  "http://m.compassedu.hk/sitemap7.txt",
  "http://m.compassedu.hk/sitemap8.txt"
]
var s = 0; //控制源的序號
var arr = []; //合并的下載地址數(shù)組
var sou = []; //源下載地址數(shù)組
var i = 0; //當前下載地址數(shù)組序號

fs.exists(__dirname+"/compassedu", function(flag){ //下載路徑檢測
  if(!flag) fs.mkdirSync(__dirname+"/compassedu"); //創(chuàng)建下載存放目錄
})
fs.exists(__dirname+"/logs", function(flag){ //日志路徑檢測
  if(!flag) fs.mkdirSync(__dirname+"/logs"); //創(chuàng)建日志存放目錄
})

if(fs.existsSync(__dirname+"/logs/compassedu_backup")){ //是否存在斷連恢復(fù)下載的控制文檔
  let obj = JSON.parse(fs.readFileSync(__dirname+"/logs/compassedu_backup")); //存在則讀取上次下載的位置
  i = obj.index;
  init(); //開始初始化程序
}
else{
  init(); //開始初始化程序
}

function init(){ //初始化
  http.get(source[s], function(res){ //獲取源下載地址文件

    //將源文件的內(nèi)容存儲到數(shù)組
    let rawData = "";
    res.setEncoding("utf8");
    res.on("data", function(chunk){ //監(jiān)聽數(shù)據(jù)流
      rawData += chunk;
    });
    res.on("end", function(){ //監(jiān)聽結(jié)束
      sou[s] = rawData.split("\n");
      console.log("源", s+1, ": ", sou[s].length, "條數(shù)據(jù)");
      s++;
      if(s<source.length){ //源文件還未讀取完
        init();
      }
      else{ //源文件讀取完畢
        for(let m=0;m<sou.length;m++){ //將所有的地址數(shù)組合并
          arr = arr.concat(sou[m]);
        }
        arr = [...new Set(arr)]; //去重
        console.log("總計: ", arr.length, "條數(shù)據(jù)", "\n爬蟲配置完畢!!\n開始爬取 >>");
        start(); //開始爬取程序
      }
    });
  })
}

function start(){ //開始
  let url = arr[i];
  console.log(url); //打印當前爬取的URL
  
  http.get(url,function(res){ //發(fā)起請求
    let obj = { //將當前的信息存儲到對象中
     "time": new Date().toLocaleTimeString(),
      "index": i,
      "url": url,
      "status": res.statusCode
    };
    fs.appendFileSync("./logs/download.log", JSON.stringify(obj), "utf8"); //寫入日志文件
    fs.writeFileSync("./logs/compassedu_backup", JSON.stringify({"index": i}), "utf8"); //將當前的下載URL序號寫入斷連恢復(fù)文件
    //讀取請求到的數(shù)據(jù)流
    let rawData = "";
    res.setEncoding("utf8");
    res.on("data", function(chunk){ //監(jiān)聽數(shù)據(jù)流事件
      rawData += chunk;
    });
    res.on("end", function(){ //監(jiān)聽結(jié)束事件
      $ = cheerio.load(rawData); //啟用類jQuery插件
      title = $(".container-public h1").text().replace(/\s/,"").trim(); //讀取數(shù)據(jù)流部分的標題
      body = $(".container-public").html(); //讀取數(shù)據(jù)流部分的內(nèi)容
      body = body.split("visible-xs")[0]; //剝離多于的數(shù)據(jù)或其他處理,準備寫入文件
      i++; //序號+1
      fs.writeFile(__dirname+"/compassedu/"+title+".html", body, "utf8", function(err){ //將處理好的數(shù)據(jù)寫入文件
        if(!err) console.log(title, "寫入成功");
        else{
          console.log(err);
        }
      });
      if(i>=arr.length) { //若序號達到數(shù)組的最后,結(jié)束程序
        console.log("爬取結(jié)束");
        fs.unlinkSync("./logs/compassedu_backup");//爬取結(jié)束,銷毀斷連恢復(fù)文件
        return;
      }
      else { //否則遞歸運行
        start();
      }
    });
    res.on("error", function(err){ //監(jiān)聽其他錯誤
      console.log(err);
    });
  })
}

至此,就結(jié)束了,是否有bug還不清楚,數(shù)據(jù)還沒爬完呢~

有bug的話,我后續(xù)補充修復(fù)~

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • nodejs中使用HTTP分塊響應(yīng)和定時器示例代碼

    nodejs中使用HTTP分塊響應(yīng)和定時器示例代碼

    本文通過示例將要創(chuàng)建一個輸出純文本的HTTP服務(wù)器,輸出的純文本每隔一秒會新增100個用換行符分隔的時間戳。實例代碼非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-03-03
  • node.js中的path.basename方法使用說明

    node.js中的path.basename方法使用說明

    這篇文章主要介紹了node.js中的path.basename方法使用說明,本文介紹了path.basename的方法說明、語法、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Nodejs實現(xiàn)的一個靜態(tài)服務(wù)器實例

    Nodejs實現(xiàn)的一個靜態(tài)服務(wù)器實例

    這篇文章主要介紹了Nodejs實現(xiàn)的一個靜態(tài)服務(wù)器實例,本文實現(xiàn)的靜態(tài)服務(wù)器實例包含cache功能、壓縮功能等,需要的朋友可以參考下
    2014-12-12
  • 利用Node.js和MySQL實現(xiàn)創(chuàng)建API服務(wù)器

    利用Node.js和MySQL實現(xiàn)創(chuàng)建API服務(wù)器

    這篇文章主要為大家詳細介紹了如何使用Node.js和MySQL創(chuàng)建API服務(wù)器的步驟,這也是從前端邁向全棧的一個開始,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2024-01-01
  • 30分鐘用Node.js構(gòu)建一個API服務(wù)器的步驟詳解

    30分鐘用Node.js構(gòu)建一個API服務(wù)器的步驟詳解

    這篇文章主要介紹了30分鐘用Node.js構(gòu)建一個API服務(wù)器的步驟詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Node.js中Process.nextTick()和Process.setImmediate()的區(qū)別

    Node.js中Process.nextTick()和Process.setImmediate()的區(qū)別

    這篇文章介紹了Node.js中Process.nextTick()和Process.setImmediate()的區(qū)別,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Node.js應(yīng)用設(shè)置安全的沙箱環(huán)境

    Node.js應(yīng)用設(shè)置安全的沙箱環(huán)境

    這篇文章主要介紹了Node.js應(yīng)用設(shè)置安全的沙箱環(huán)境的方法以及注意事項,對此有需要的朋友可以參考學(xué)習(xí)下。
    2018-04-04
  • Node.js圖片處理庫sharp的使用

    Node.js圖片處理庫sharp的使用

    這篇文章主要介紹了Node.js圖片處理庫sharp的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Nodejs sublime text 3安裝與配置

    Nodejs sublime text 3安裝與配置

    Sublime Text是一個輕量、簡潔、高效、跨平臺的編輯器,方便的配色以及兼容vim快捷鍵等各種優(yōu)點博得了很多前端開發(fā)人員的喜愛!Sublime Text這款程序員必備代碼編輯器,幾乎每位程序員提到Sublime Text都是贊不絕口!它體積小巧,無需安裝,綠色便攜
    2014-06-06
  • Node.js包管理工具

    Node.js包管理工具

    本文主要詳細介紹了node包管理工具,主要介紹了npm,cnpm及yarn,文中有詳細的代碼示例,對學(xué)習(xí)具有一定參考價值,需要的朋友可以參考一下
    2023-04-04

最新評論