国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

puppeteer_node爬蟲分布式進階

sutaking / 1702人閱讀

摘要:前面的文章將做爬蟲的基礎一直到部署都梳理了一遍,現在來看一下分布式的處理為什么需要分布式需要抓取的不同數據有很多,會同時開啟無頭瀏覽器去抓取,然后獲取到數據后又無厘頭的一股腦擠進數據庫無法保證同一時刻需要的數據只有一個操作在進行分布式選擇因

前面的文章將puppeteer做爬蟲的基礎一直到部署都梳理了一遍,現在來看一下分布式的處理 1) 為什么需要分布式
   1. 需要抓取的不同數據有很多,會同時開啟無頭瀏覽器去抓取,然后獲取到數據后又無厘頭的一股腦擠進數據庫
   2. 無法保證同一時刻需要的數據只有一個操作在進行
2) 分布式選擇
因為使用的是node,所以盡可能的尋找node支持的分布式框架
ZooKeeper 和 RabbitMQ 的思想百度上有好多說明,讀者可以自行搜索作更詳細的了解
node版的zookeeper
node版的RabbitMQ
3) 銜接之前的 puppeteer進階版_爬取書旗小說 文章內容,文章只是放了一些主要的代碼,末尾會附上項目地址,大家可以去擼一擼
發布者,給書旗起一個標識為 37 (channel_id),然后是要抓取書的書籍id(channel_book_id)
// 我們以接口的形式接收爬取的參數    
// 簡易版請求(除了接收參數不做任何處理) -> 發布者
app.get("/v1.0/grasp_book", (req, res, next) => {
  // 抓取時需要的參數
  if (!req.query.channel_id && !req.query.channel_book_id) {
    res.send({
      code: 403,
      msg: "params error"
    })
    return null;
  }
  // 發布者
  // 連接rabbitmq
  amqp.connect("amqp://rabbitmq:12345678@127.0.0.1:5672/").then(function(conn) {
    return conn.createChannel().then(function(ch) {
      // 創建 hello 的消息隊列
      var q = "hello";
      // 解析為json字符串格式作為傳遞的數據格式
      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) {
        // 發送數據到消費者
        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"
  });
}); 
命令行啟動app.js,發出請求并查看結果,{} 里面的就是我們發送出去的數據


消費者以及ZooKeeper
消費者,接收到發布者傳遞過來的數據建立消息隊列,然后用Zookeeper創建臨時節點以保持隊列依次執行
var zookeeper = require("node-zookeeper-client");

// 根據標識動態引入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:12345678@127.0.0.1:5672/").then(function(conn) {
    return conn.createChannel().then(function(ch) {
      // 與名為 hello(由發布者創建) 的消息隊列建立連接
      var ok = ch.assertQueue("hello", {durable: true});
      // 預存為1
      ok = ok.then(function() { ch.prefetch(1); });
      ok = ok.then(function() {
        // doWork 回調函數 -> 執行接收到數據后的操作
        ch.consume("hello", doWork, {noAck: false});
      });
      return ok;
      // rabbitmq 處理
      function doWork(msg) {
          // 接收到數據
          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 節點
          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.");
                // 存在則不執行,但需要將數據傳遞下去
                // ack 可以參考 https://www.jianshu.com/p/a5f7fce67803
                ch.ack(msg);
              } else {
                  console.log("Node does not exist.");
                  // 操作完成后則釋放當前創建的臨時節點
                  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);
                          
                        // 根據傳入標識(如書旗就是37)動態引入js文件(抓書的操作)
                        moduleCustomize(channel_id).init(channel_book_id)

                        // 傳遞數據
                        ch.ack(msg);
                        // 釋放當前創建的臨時節點
                        client.remove(path, -1, function (error) {
                            if (error) {
                                console.log(error.stack);
                                return;
                            }
                            console.log("Node is deleted.");
                        });

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


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

4) 查看mongo結果數據

5) 項目地址(update分支)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93256.html

相關文章

  • 非計算機專業小白自學爬蟲全指南(附資源)

    摘要:爬蟲是我接觸計算機編程的入門。練練練本文推薦的資源就是以項目練習帶動爬蟲學習,囊括了大部分爬蟲工程師要求的知識點。拓展閱讀一文了解爬蟲與反爬蟲最后,請注意,爬蟲的工作機會相對較少。 爬蟲是我接觸計算機編程的入門。哥當年寫第一行代碼的時候別提有多痛苦。 本文旨在用一篇文章說透爬蟲如何自學可以達到找工作的要求。 爬蟲的學習就是跟著實際項目去學,每個項目會涉及到不同的知識點,項目做多了,自然...

    CarlBenjamin 評論0 收藏0
  • 超詳細的Python實現百度云盤模擬登陸(模擬登陸進階)

    摘要:方法不僅適用于百度云,別的一些比較難以模擬登陸的網站都可以按照這種方式分析。本文要求讀者具有模擬登陸主要是抓包和閱讀代碼和密碼學的基本知識。和模擬登陸微博的分析流程一樣,我們首先要做的是以正常人的流程完整的登錄一遍百度網盤。 這是第二篇從簡書搬運過來的文章(大家別誤會,是我原創的)。因為前一篇文章,我看反響還挺好的,所以把這篇也搬運過來了,其實目的還是為宣傳自己的分布式微博爬蟲(該項目...

    CarterLi 評論0 收藏0
  • 零基礎如何學爬蟲技術

    摘要:楚江數據是專業的互聯網數據技術服務,現整理出零基礎如何學爬蟲技術以供學習,。本文來源知乎作者路人甲鏈接楚江數據提供網站數據采集和爬蟲軟件定制開發服務,服務范圍涵蓋社交網絡電子商務分類信息學術研究等。 楚江數據是專業的互聯網數據技術服務,現整理出零基礎如何學爬蟲技術以供學習,http://www.chujiangdata.com。 第一:Python爬蟲學習系列教程(來源于某博主:htt...

    KunMinX 評論0 收藏0
  • Python從入門到轉行

    摘要:學了大半年之后成功轉行做前端了。包含大量其他神經網絡庫中的包裝器和抽象,其中最值得注意的是,其中也包含一些機器學習的實用模塊。它是輕量級可擴展的神經網絡工具包,同時擁有友好的界面,可供機器學習的訓練和預測使用。 題記:大二的時候發現人生苦短,所以信了拍神,開始學Python。學了大半年之后成功轉行做前端了。來寫個教程幫助大家入門Python。 Python零基礎入門 零基礎入門就得從最...

    ingood 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<