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

使用async、enterproxy控制并發(fā)數(shù)量的方法詳解

 更新時間:2018年01月02日 08:21:16   作者:OkayChen  
并發(fā)相信對大家來說都不陌生,這篇文章主要給大家介紹了關于使用async、enterproxy控制并發(fā)數(shù)量的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

聊聊并發(fā)與并行

并發(fā),在操作系統(tǒng)中,是指一個時間段中有幾個程序都處于已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行。

并發(fā)我們經常提及之,不管是web server,app并發(fā)無處不在,操作系統(tǒng)中,指一個時間段中幾個程序處于已經啟動運行到完畢之間,且這幾個程序都是在同一處理機上運行,并且任一個時間點只有一個程序在處理機上運行。很多網站都有并發(fā)連接數(shù)量的限制,所以當請求發(fā)送太快的時候會導致返回值為空或報錯。更有甚者,有些網站可能因為你發(fā)出的并發(fā)連接數(shù)量過多而當你是在惡意請求,封掉你的ip。

相對于并發(fā),并行可能陌生了不少,并行指一組程序按獨立異步的速度執(zhí)行,不等于時間上的重疊(同一個時刻發(fā)生),通過增加cpu核心來實現(xiàn)多個程序(任務)的同時進行。沒錯,并行做到了多任務的同時進行

使用enterproxy控制并發(fā)數(shù)量

enterproxy是樸靈大大為主要貢獻的工具,帶來一種事件式編程的思維變化,利用事件機制解耦復雜業(yè)務邏輯,解決了回調函數(shù)耦合性的詬病,將串行等待變成并行等待,提升多異步協(xié)作場景下的執(zhí)行效率

我們如何使用enterproxy控制并發(fā)數(shù)量?通常如果我們不使用enterproxy和自制的計數(shù)器,我們如果抓取三個源:

這種深層嵌套,串行的方式

 var render = function (template, data) {
 _.template(template, data);
 };
$.get("template", function (template) {
 // something
 $.get("data", function (data) {
 // something
 $.get("l10n", function (l10n) {
 // something
 render(template, data, l10n);
 });
 });
});

除去這種過去深層嵌套的方法,我們常規(guī)的寫法的自己維護一個計數(shù)器

(function(){
 var count = 0;
 var result = {};
 
 $.get('template',function(data){
 result.data1 = data;
 count++;
 handle();
 })
 $.get('data',function(data){
 result.data2 = data;
 count++;
 handle();
 })
 $.get('l10n',function(data){
 result.data3 = data;
 count++;
 handle();
 })

 function handle(){
 if(count === 3){
  var html = fuck(result.data1,result.data2,result.data3);
  render(html);
 }
 }
})();

在這里,enterproxy就可以起到這個計數(shù)器的作用,它幫你管理這些異步操作是否完成,完成之后,他會自動調用你提供的處理函數(shù),并將抓取到數(shù)據當做參數(shù)傳遞過來

var ep = new enterproxy();
ep.all('data_event1','data_event2','data_event3',function(data1,data2,data3){
 var html = fuck(data1,data2,data3);
 render(html);
})

$.get('http:example1',function(data){
 ep.emit('data_event1',data);
})

$.get('http:example2',function(data){
 ep.emit('data_event2',data);
})

$.get('http:example3',function(data){
 ep.emit('data_event3',data);
})

enterproxy還提供了其他不少場景所需的API,可以自行學習下這個API enterproxy

使用async控制并發(fā)數(shù)量

假如我們有40個請求需要發(fā)出,很多網站可能會因為你發(fā)出的并發(fā)連接數(shù)太多而當你是在惡意請求,把你的IP封掉。
所以我們總是需要控制并發(fā)數(shù)量,然后慢慢抓取完這40個鏈接。

使用async中mapLimit控制一次性并發(fā)數(shù)量為5,一次性只抓取5個鏈接。

 async.mapLimit(arr, 5, function (url, callback) {
 // something
 }, function (error, result) {
 console.log("result: ")
 console.log(result);
 })

我們首先應該知道什么是并發(fā),為什么需要限制并發(fā)數(shù)量,都有哪些處理方案。然后就可以去文檔具體看一下API如何使用。async文檔可以很好的學習這些語法。

模擬一組數(shù)據,這里返回的數(shù)據是假的,返回的延時是隨機的。

var concurreyCount = 0;
var fetchUrl = function(url,callback){
 // delay 的值在 2000 以內,是個隨機的整數(shù) 模擬延時
 var delay = parseInt((Math.random()* 10000000) % 2000,10);
 concurreyCount++;
 console.log('現(xiàn)在并發(fā)數(shù)是 ' , concurreyCount , ' 正在抓取的是' , url , ' 耗時' + delay + '毫秒');
 setTimeout(function(){
 concurreyCount--;
 callback(null,url + ' html content');
 },delay);
}

var urls = [];
for(var i = 0;i<30;i++){
 urls.push('http://datasource_' + i)
}

然后我們使用async.mapLimit來并發(fā)抓取,并獲取結果。

async.mapLimit(urls,5,function(url,callback){
 fetchUrl(url,callbcak);
},function(err,result){
 console.log('result: ');
 console.log(result);
})

模擬摘自alsotang

運行輸出后得到以下結果

我們發(fā)現(xiàn),并發(fā)數(shù)從1開始增長,但是增長到5時,就不在增加。然有任務時就繼續(xù)抓取,并發(fā)連接數(shù)量始終控制在5個。

完成node簡易爬蟲系統(tǒng)

因為alsotang前輩的《node包教不包會》教程例子中使用的eventproxy控制的并發(fā)數(shù)量,我們就來完成一個使用async控制并發(fā)數(shù)量的node簡易爬蟲。

爬取的目標就是本站首頁(手動護臉)

第一步,首先我們需要用到以下的模塊:

  • url : 用于url解析,這里用到url.resolve()生成一個合法的域名
  • async : 一個實用的模塊,提供了強大的功能和異步JavaScript工作
  • cheerio : 為服務器特別定制的,快速,靈活,實施的jQuery核心實現(xiàn)
  • superagent : nodejs里一個非常方便的客戶端請求代理模塊

通過npm安裝依賴模塊


第二步,通過require引入依賴模塊,確定爬取對象URL:

var url = require("url");
var async = require("async");
var cheerio = require("cheerio");
var superagent = require("superagent");
var baseUrl = 'http://www.chenqaq.com';

第三步:使用superagent請求目標URL,并使用cheerio處理baseUrl得到目標內容url,并保存在數(shù)組arr中

superagent.get(baseUrl)
 .end(function (err, res) {
 if (err) {
  return console.error(err);
 }
 var arr = [];
 var $ = cheerio.load(res.text);
 // 下面和jQuery操作是一樣一樣的..
 $(".post-list .post-title-link").each(function (idx, element) {
  $element = $(element);
  var _url = url.resolve(baseUrl, $element.attr("href"));
  arr.push(_url);
 });
 // 驗證得到的所有文章鏈接集合
 output(arr);
 // 第四步:接下來遍歷arr,解析每一個頁面需要的信息
})

我們需要一個函數(shù)驗證抓取的url對象,很簡單我們只需要一個函數(shù)遍歷arr并打印出來就可以:

function output(arr){
 for(var i = 0;i<arr.length;i++){
  console.log(arr[i]);
 }
}

第四步:我們需要遍歷得到的URL對象,解析每一個頁面需要的信息。

這里就需要用到async控制并發(fā)數(shù)量,如果你上一步獲取了一個龐大的arr數(shù)組,有多個url需要請求,如果同時發(fā)出多個請求,一些網站就可能會把你的行為當做惡意請求而封掉你的ip

async.mapLimit(arr,3,function(url,callback){
 superagent.get(url)
  .end(function(err,mes){
   if(err){
    console.error(err);
    console.log('message info ' + JSON.stringify(mes));
   }
   console.log('「fetch」' + url + ' successful!');
   var $ = cheerio.load(mes.text);
   var jsonData = {
    title:$('.post-card-title').text().trim(),
    href: url,
   };
   callback(null,jsonData);
  },function(error,results){
   console.log('results ');
   console.log(results);
  })
 })

得到上一步保存url地址的數(shù)組arr,限制最大并發(fā)數(shù)量為3,然后用一個回調函數(shù)處理 「該回調函數(shù)比較特殊,在iteratee方法中一定要調用該回調函數(shù),有三種方式」

  • callback(null) 調用成功
  • callback(null,data) 調用成功,并且返回數(shù)據data追加到results
  • callback(data) 調用失敗,不會再繼續(xù)循環(huán),直接到最后的callback

好了,到這里我們的node簡易的小爬蟲就完成了,來看看效果吧

嗨呀,首頁數(shù)據好少,但是成功了呢。

參考資料

Node.js 包教不包會 - alsotang

enterproxy

async

async Documentation

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Node.js 中如何收集和解析命令行參數(shù)

    Node.js 中如何收集和解析命令行參數(shù)

    這篇文章主要介紹了Node.js 中如何收集和解析命令行參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • Node升級后vue項目node-sass報錯問題及解決

    Node升級后vue項目node-sass報錯問題及解決

    這篇文章主要介紹了Node升級后vue項目node-sass報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • npm安裝依賴報錯ERESOLVE?unable?to?resolve?dependency?tree的解決方法

    npm安裝依賴報錯ERESOLVE?unable?to?resolve?dependency?tree的解決方

    當我們拿到一個前端項目的時候,想要把它運行起來,首先是要給它安裝依賴,下面這篇文章主要給大家介紹了關于npm安裝依賴報錯ERESOLVE?unable?to?resolve?dependency?tree的解決方法,需要的朋友可以參考下
    2023-04-04
  • node中koa中間件機制詳解

    node中koa中間件機制詳解

    本篇文章主要主要介紹了node中koa中間件機制詳解,詳細的介紹了koa和兼容問題,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • npm下載慢或下載失敗問題解決的三種方法

    npm下載慢或下載失敗問題解決的三種方法

    這篇文章主要為大家介紹了npm下載慢或下載失敗問題解決的三種方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Node.js的特點和應用場景介紹

    Node.js的特點和應用場景介紹

    這篇文章主要介紹了Node.js的特點和應用場景介紹,本文講解了Node.js的異步I/O、 事件循環(huán)與回調函數(shù)、單線程、 跨平臺等特性,然后總結了它的使用場景,需要的朋友可以參考下
    2014-11-11
  • node.js中路由,中間件,get請求和post請求的參數(shù)詳解

    node.js中路由,中間件,get請求和post請求的參數(shù)詳解

    本文給大家匯總介紹了node.js中的路由,中間件,get請求和post請求的參數(shù)的使用方法,非常的詳細,有需要的小伙伴可以參考下
    2017-12-12
  • Nodejs 識別圖片類型的方法

    Nodejs 識別圖片類型的方法

    這篇文章主要介紹了Nodejs 識別圖片類型的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • nodejs中用npm初始化來創(chuàng)建package.json的實例講解

    nodejs中用npm初始化來創(chuàng)建package.json的實例講解

    今天小編就為大家分享一篇nodejs中用npm初始化來創(chuàng)建package.json的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • node.js中的emitter.emit方法使用說明

    node.js中的emitter.emit方法使用說明

    這篇文章主要介紹了node.js中的emitter.emit方法使用說明,本文介紹了emitter.emit的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12

最新評論