我试图废弃数千页。所以我使用了async.timesSeries和async.waterfall。每个功能都可以很好地同步工作,但它们不能一起工作。我该怎么办?
逻辑很简单。
因为我想要抓取页面是“http://udb.kr/local/category/390101?page=”1~1167,async.timesSeries循环1到1167
async.waterfall废弃网页的组件
但是控制台向我显示的消息看起来像这样
info.NM values // just for explain, It shows me each attires of obj because I insert console.log(info.NM) for verifying.
info.NM values
info.NM values
info.NM values and randomly ----- page number -----
...
['done',
'done',
'done',
'done',
'done',
...
'done']
info.NM values again
.../Users/Snark/Dev/job_apply/cheerio_job_app_list.js:29
if (tObj[m+1].children != 0) {info.nAddr = tObj[m+1].firstChild.data}else{info.nAddr = null};
^
TypeError: Cannot read property 'children' of undefined
at /Users/Snark/Dev/job_apply/cheerio_job_app_list.js:29:17
at fn (/Users/Snark/node_modules/async/lib/async.js:746:34)
at /Users/Snark/node_modules/async/lib/async.js:1212:16
at /Users/Snark/node_modules/async/lib/async.js:166:37
at /Users/Snark/node_modules/async/lib/async.js:706:43
at /Users/Snark/node_modules/async/lib/async.js:167:37
at /Users/Snark/node_modules/async/lib/async.js:1208:30
at Request._callback (/Users/Snark/Dev/job_apply/cheerio_job_app_list.js:21:6)
at Request.self.callback (/Users/Snark/node_modules/request/request.js:198:22)
at emitTwo (events.js:87:13)
这是js代码。
var request = require("request"),
cheerio = require("cheerio"),
jsonfile = require("jsonfile"),
fs = require("fs"),
async = require("async");
var info = {},
dbArray = [];
var url = "http://udb.kr/local/category/390101?page=";
async.timesSeries(1166, function(n, next) {
var page = n + 1
async.waterfall([
function(callback) {
request(url + page, function(error, response, html) {
if (error) {
throw error
};
var $ = cheerio.load(html),
tObj = $('tbody tr td');
callback(null, tObj);
});
},
function(tObj, callback) {
for (var m = 0; m < 150; m = m + 5) {
if (tObj[m]) {
info.NM = tObj[m].firstChild.children[0].data
} else {
info.NM = null
};
if (tObj[m + 1].children != 0) {
info.nAddr = tObj[m + 1].firstChild.data
} else {
info.nAddr = null
};
console.log(info.NM);
dbArray.push(info);
}
callback(dbArray, callback);
},
function(dbArray, callback) {
fs.appendFile('./jobDB_l.json', JSON.stringify(dbArray), function (err) {
if (err)
throw err;
});
callback(null, 'done');
}
], function(err, result) {
console.log('----- ' +page+ '-----');
});
next(null, 'done');
}, function(err, result) {
console.log(result)
});
答案 0 :(得分:0)
if (tObj[m+1] && tObj[m+1].children != 0)
答案 1 :(得分:0)
要使这些在每个timesSeries迭代中使用瀑布的方式协同工作,您需要从瀑布调用的完成回调中调用timesSeries done
回调。现在,你在很久之前调用它,这意味着timesSeries不会等待瀑布完成。
你可以通过改变这个来做到这一点:
], function(err, result) {
console.log('----- ' +page+ '-----');
});
next(null, 'done');
到此:
], function(err, result) {
console.log('----- ' +page+ '-----');
next(null, 'done');
});
您使用for
的硬编码m < 150
循环限制而不是使用内容的实际长度,这似乎很奇怪。您可以轻松地运行内容的末尾并可能导致问题。
而且,您的错误处理可能也无法正常工作。如果你在异步throw
回调中request()
,那就不会去任何地方了。您需要更好的错误处理,例如调用callback(error)
将错误传递给async.waterfall()
。
你也可能希望在try / catch中包围所有DOM,所以如果你在那里抛出任何异常,你可以自己捕获它们,分析它们然后修复代码。