成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

puppeteer_node爬蟲(chóng)分布式進(jìn)階

sutaking / 1728人閱讀

摘要:前面的文章將做爬蟲(chóng)的基礎(chǔ)一直到部署都梳理了一遍,現(xiàn)在來(lái)看一下分布式的處理為什么需要分布式需要抓取的不同數(shù)據(jù)有很多,會(huì)同時(shí)開(kāi)啟無(wú)頭瀏覽器去抓取,然后獲取到數(shù)據(jù)后又無(wú)厘頭的一股腦擠進(jìn)數(shù)據(jù)庫(kù)無(wú)法保證同一時(shí)刻需要的數(shù)據(jù)只有一個(gè)操作在進(jìn)行分布式選擇因

前面的文章將puppeteer做爬蟲(chóng)的基礎(chǔ)一直到部署都梳理了一遍,現(xiàn)在來(lái)看一下分布式的處理 1) 為什么需要分布式
   1. 需要抓取的不同數(shù)據(jù)有很多,會(huì)同時(shí)開(kāi)啟無(wú)頭瀏覽器去抓取,然后獲取到數(shù)據(jù)后又無(wú)厘頭的一股腦擠進(jìn)數(shù)據(jù)庫(kù)
   2. 無(wú)法保證同一時(shí)刻需要的數(shù)據(jù)只有一個(gè)操作在進(jìn)行
2) 分布式選擇
因?yàn)槭褂玫氖莕ode,所以盡可能的尋找node支持的分布式框架
ZooKeeper 和 RabbitMQ 的思想百度上有好多說(shuō)明,讀者可以自行搜索作更詳細(xì)的了解
node版的zookeeper
node版的RabbitMQ
3) 銜接之前的 puppeteer進(jìn)階版_爬取書(shū)旗小說(shuō) 文章內(nèi)容,文章只是放了一些主要的代碼,末尾會(huì)附上項(xiàng)目地址,大家可以去擼一擼
發(fā)布者,給書(shū)旗起一個(gè)標(biāo)識(shí)為 37 (channel_id),然后是要抓取書(shū)的書(shū)籍id(channel_book_id)
// 我們以接口的形式接收爬取的參數(shù)    
// 簡(jiǎn)易版請(qǐng)求(除了接收參數(shù)不做任何處理) -> 發(fā)布者
app.get("/v1.0/grasp_book", (req, res, next) => {
  // 抓取時(shí)需要的參數(shù)
  if (!req.query.channel_id && !req.query.channel_book_id) {
    res.send({
      code: 403,
      msg: "params error"
    })
    return null;
  }
  // 發(fā)布者
  // 連接rabbitmq
  amqp.connect("amqp://rabbitmq:[email protected]:5672/").then(function(conn) {
    return conn.createChannel().then(function(ch) {
      // 創(chuàng)建 hello 的消息隊(duì)列
      var q = "hello";
      // 解析為json字符串格式作為傳遞的數(shù)據(jù)格式
      var msg = JSON.stringify({
        "channel_id": req.query.channel_id,
        "book_id": req.query.book_id
      })
      // 連接并保持
      var ok = ch.assertQueue(q, {durable: true});
      return ok.then(function(_qok) {
        // 發(fā)送數(shù)據(jù)到消費(fèi)者
        ch.sendToQueue(q, Buffer.from(msg));
        console.log(" [x] Sent "%s"", msg);
        return ch.close();
      });
    }).finally(function() { conn.close(); });
  }).catch(console.warn);
  res.send({
    code: 200,
    msg: "success"
  });
}); 
命令行啟動(dòng)app.js,發(fā)出請(qǐng)求并查看結(jié)果,{} 里面的就是我們發(fā)送出去的數(shù)據(jù)


消費(fèi)者以及ZooKeeper
消費(fèi)者,接收到發(fā)布者傳遞過(guò)來(lái)的數(shù)據(jù)建立消息隊(duì)列,然后用Zookeeper創(chuàng)建臨時(shí)節(jié)點(diǎn)以保持隊(duì)列依次執(zhí)行
var zookeeper = require("node-zookeeper-client");

// 根據(jù)標(biāo)識(shí)動(dòng)態(tài)引入js文件
function moduleCustomize(channel_id) {
    return require(`../${channel_id}.js`)
}

 
var client = zookeeper.createClient("127.0.0.1:2181");

async function sleep(second) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("sleep")
    }, second)
  })
}

// 連接_zookeeper
client.once("connected", function () {
  console.log("Connected to the server.");
  // 建立連接 rabbitmp
  amqp.connect("amqp://rabbitmq:[email protected]:5672/").then(function(conn) {
    return conn.createChannel().then(function(ch) {
      // 與名為 hello(由發(fā)布者創(chuàng)建) 的消息隊(duì)列建立連接
      var ok = ch.assertQueue("hello", {durable: true});
      // 預(yù)存為1
      ok = ok.then(function() { ch.prefetch(1); });
      ok = ok.then(function() {
        // doWork 回調(diào)函數(shù) -> 執(zhí)行接收到數(shù)據(jù)后的操作
        ch.consume("hello", doWork, {noAck: false});
      });
      return ok;
      // rabbitmq 處理
      function doWork(msg) {
          // 接收到數(shù)據(jù)
          var body = msg.content.toString();
          console.log("[x] Received "%s"", body);
          let _body = JSON.parse(body)
          let channel_book_id = _body["channel_book_id"];
          let channel_id = _body["channel_id"];
          // zookeeper 節(jié)點(diǎn)
          let path = `/${channel_id + "_" + channel_book_id}`
          // 連接_zookeeper 判斷是否存在
          client.exists(path, function (error, stat) {
              if (error) {
                  console.log(error.stack);
                  return;
              }
              if (stat) {
                console.log("Node exists.");
                // 存在則不執(zhí)行,但需要將數(shù)據(jù)傳遞下去
                // ack 可以參考 https://www.jianshu.com/p/a5f7fce67803
                ch.ack(msg);
              } else {
                  console.log("Node does not exist.");
                  // 操作完成后則釋放當(dāng)前創(chuàng)建的臨時(shí)節(jié)點(diǎn)
                  client.create(path, null, zookeeper.CreateMode.EPHEMERAL, function (error) {
                    if (error) {
                        console.log("Failed to create node: %s due to: %s.", path, error);
                    } else {
                        console.log("Node: %s is successfully created.", path);
                          
                        // 根據(jù)傳入標(biāo)識(shí)(如書(shū)旗就是37)動(dòng)態(tài)引入js文件(抓書(shū)的操作)
                        moduleCustomize(channel_id).init(channel_book_id)

                        // 傳遞數(shù)據(jù)
                        ch.ack(msg);
                        // 釋放當(dāng)前創(chuàng)建的臨時(shí)節(jié)點(diǎn)
                        client.remove(path, -1, function (error) {
                            if (error) {
                                console.log(error.stack);
                                return;
                            }
                            console.log("Node is deleted.");
                        });

                    }
                  });
                }
              console.log("任務(wù)執(zhí)行完畢")
            });
      }
    });
  }).catch(console.warn);


});
 
client.connect();
命令行啟動(dòng)rab_consumer.js,{} 里面就是我們接收到消息隊(duì)列里面的數(shù)據(jù)了

4) 查看mongo結(jié)果數(shù)據(jù)

5) 項(xiàng)目地址(update分支)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93256.html

相關(guān)文章

  • 非計(jì)算機(jī)專業(yè)小白自學(xué)爬蟲(chóng)全指南(附資源)

    摘要:爬蟲(chóng)是我接觸計(jì)算機(jī)編程的入門(mén)。練練練本文推薦的資源就是以項(xiàng)目練習(xí)帶動(dòng)爬蟲(chóng)學(xué)習(xí),囊括了大部分爬蟲(chóng)工程師要求的知識(shí)點(diǎn)。拓展閱讀一文了解爬蟲(chóng)與反爬蟲(chóng)最后,請(qǐng)注意,爬蟲(chóng)的工作機(jī)會(huì)相對(duì)較少。 爬蟲(chóng)是我接觸計(jì)算機(jī)編程的入門(mén)。哥當(dāng)年寫(xiě)第一行代碼的時(shí)候別提有多痛苦。 本文旨在用一篇文章說(shuō)透爬蟲(chóng)如何自學(xué)可以達(dá)到找工作的要求。 爬蟲(chóng)的學(xué)習(xí)就是跟著實(shí)際項(xiàng)目去學(xué),每個(gè)項(xiàng)目會(huì)涉及到不同的知識(shí)點(diǎn),項(xiàng)目做多了,自然...

    CarlBenjamin 評(píng)論0 收藏0
  • 超詳細(xì)的Python實(shí)現(xiàn)百度云盤(pán)模擬登陸(模擬登陸進(jìn)階)

    摘要:方法不僅適用于百度云,別的一些比較難以模擬登陸的網(wǎng)站都可以按照這種方式分析。本文要求讀者具有模擬登陸主要是抓包和閱讀代碼和密碼學(xué)的基本知識(shí)。和模擬登陸微博的分析流程一樣,我們首先要做的是以正常人的流程完整的登錄一遍百度網(wǎng)盤(pán)。 這是第二篇從簡(jiǎn)書(shū)搬運(yùn)過(guò)來(lái)的文章(大家別誤會(huì),是我原創(chuàng)的)。因?yàn)榍耙黄恼?,我看反響還挺好的,所以把這篇也搬運(yùn)過(guò)來(lái)了,其實(shí)目的還是為宣傳自己的分布式微博爬蟲(chóng)(該項(xiàng)目...

    CarterLi 評(píng)論0 收藏0
  • 零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)

    摘要:楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)以供學(xué)習(xí),。本文來(lái)源知乎作者路人甲鏈接楚江數(shù)據(jù)提供網(wǎng)站數(shù)據(jù)采集和爬蟲(chóng)軟件定制開(kāi)發(fā)服務(wù),服務(wù)范圍涵蓋社交網(wǎng)絡(luò)電子商務(wù)分類信息學(xué)術(shù)研究等。 楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)以供學(xué)習(xí),http://www.chujiangdata.com。 第一:Python爬蟲(chóng)學(xué)習(xí)系列教程(來(lái)源于某博主:htt...

    KunMinX 評(píng)論0 收藏0
  • Python從入門(mén)到轉(zhuǎn)行

    摘要:學(xué)了大半年之后成功轉(zhuǎn)行做前端了。包含大量其他神經(jīng)網(wǎng)絡(luò)庫(kù)中的包裝器和抽象,其中最值得注意的是,其中也包含一些機(jī)器學(xué)習(xí)的實(shí)用模塊。它是輕量級(jí)可擴(kuò)展的神經(jīng)網(wǎng)絡(luò)工具包,同時(shí)擁有友好的界面,可供機(jī)器學(xué)習(xí)的訓(xùn)練和預(yù)測(cè)使用。 題記:大二的時(shí)候發(fā)現(xiàn)人生苦短,所以信了拍神,開(kāi)始學(xué)Python。學(xué)了大半年之后成功轉(zhuǎn)行做前端了。來(lái)寫(xiě)個(gè)教程幫助大家入門(mén)Python。 Python零基礎(chǔ)入門(mén) 零基礎(chǔ)入門(mén)就得從最...

    ingood 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<