最近在看<包教不包会>教程,遇到上一些问题不太明白
- 为什么会有时能爬到数据,有时却爬不到数据呢?
- async.mapLimit 这个接口有点疑问?这个是每爬完一条 url 就返回的结果数据吗?如果是,那么我怎样才能知道所有数据已爬完毕呢?
代码如下:
var express = require('express');
var superagent = require('superagent');
var cheerio = require('cheerio');
var url = require('url');
var async = require('async');
var app = express();
app.get('/', function(req, res){
var targetUrl = 'https://cnodejs.org';
superagent.get(targetUrl).end(function(err, html){
if(err){
console.error('urls: ', err);
}
var $ = cheerio.load(html.text);
var urls = [];
// 获取所有链接
$('#topic_list .topic_title').each(function(key, value){
var $obj = $(value);
var href = $obj.attr('href');
var link = url.resolve(targetUrl, href)
urls.push(link);
});
// 定义当前并发数
var concurrencyCount = 0;
function fetchUrls(url, callback){
// 抓取单条主题的内容
var topic = {};
superagent.get(url).end(function(err, thtml){
var $ = cheerio.load(thtml);
var title = $('#content .topic_header .topic_full_title').text().trim();
var content = $('#content .topic_content .markdown-text').text().trim();
var link = url;
topic = {
"title" : title,
"content" : content,
"link" : link
};
});
// 随机间隔时间
var delay = parseInt((Math.random() * 10000000) % 3000, 10);
concurrencyCount++;
console.log('当前并发数是'+ concurrencyCount +', 正在抓取的是'+ url +', 耗时'+ delay + '毫秒.');
setTimeout(function(){
concurrencyCount--;
callback(null, topic);
}, delay);
}
// 控制并发数
async.mapLimit(urls, 3, function(url, callback){
fetchUrls(url, callback);
}, function(err, result){
if(err){
console.error('final: ', err);
}
console.log('final: ', result);
res.send(result);
});
});
});
app.listen(4000, function(){
console.log('hello cnodejs.');
});
谢谢你看到这里.
1 回复