L'idée actuelle est la suivante : 1. Obtenez toutes les URL des pages de balises sous la catégorie, 2. Parcourez la page d'exploration pour récupérer la page de balises actuelle afin d'obtenir l'adresse API json, 3. Récupérez la liste de produits de la balise actuelle. , 4. Récupérez les produits en cours de chargement dans les pages à onglets.
Mais ce qui est fait maintenant, c'est qu'au début de la deuxième étape, il n'attend pas que 2-4 soit terminé avant de passer à la suivante. J'ai essayé d'utiliser async/await, mais le contrôle de processus n'a pas été implémenté. Demander conseil ici.
var http = require('http');
var fs = require("fs");
var superagent = require('superagent');
var urls = [];
var pageIndex = 1;
var xlsxData = '';
getGoodsUrl(urls);
function getGoodsUrl(urls){
superagent
.post('http://bravetime.davdian.com/index.php?c=Index&a=getCatNavList')
.type('text/html; charset=utf-8')
.set('Accept','application/json, text/javascript, */*; q=0.01')
.end(function(err, res) {
if (err) {
console.log('分类数据请求失败');
} else {
console.log('分类数据请求成功');
var resData = res.text;
var resData = JSON.parse(resData);
if(resData.data.length > 0){
resData.data.forEach(function(item){
var rowObj = [];
var title = item.title;
var category = item.content.category;
category.forEach(function(item){
var text = [];
text.push(title+ '--' + item.text);
text.push(item.link);
rowObj.push(text);
});
urls.push(rowObj);
});
loopUrls(urls);
} else {
console.log('分类数据为空');
}
// saveInfo(xlsxData);
}
})
}
function loopUrls(urls){
urls.forEach(function(item){
var row = item;
row.forEach(function(item){
var tagTitie = item[0];
var tegUrl = item[1];
getApiUrl(tagTitie,tegUrl);
});
});
}
function getApiUrl(title,url){
var realUrl = 'http://bravetime.davdian.com' + url;
http.get(realUrl,function(res){
var html = '';
res.on('data',function(data){
html += data;
});
res.on('end',function(){
console.log('正在获取' + title + '页面数据');
var reg = /goodsUrl = "(.+)"/;
var apiUrl = reg.exec(html);
getGoodsJson(apiUrl[1],pageIndex);
});
}).on('error',function(){
console.log('获取html出错!!');
});
}
function getGoodsJson(url,pageIndex){
superagent
.post('http://bravetime.davdian.com/' + url + 'page_size=10&rp=catergory_search&rl=list')
.send({page:pageIndex})
.type('application/x-www-form-urlencoded; charset=UTF-8')
.set('Accept','application/json, text/javascript, */*; q=0.01')
.end(function(err, res) {
if (err) {
console.log('第' + pageIndex + '页请求失败');
} else {
console.log('第' + pageIndex + '页请求成功');
var resData = res.text;
var resData = JSON.parse(resData);
if(resData.data.length > 0){
resData.data.forEach(function(item){
xlsxData = xlsxData + item.goods_name + ' ' + item.shop_price + ' ' + item.goods_number + '\r\n';
});
pageIndex = parseInt(pageIndex) + 1;
setTimeout(function(){
getGoodsJson(url,pageIndex);
},200);
} else {
console.log('数据已加载完毕');
saveTxt(xlsxData);
pageIndex = 1;
return false;
}
// saveInfo(xlsxData);
}
})
}
function saveTxt(data){
fs.writeFile("create.txt",data,function (err) {
if (err) throw err ;
console.log("File Saved !"); //文件被保存
}) ;
}
function saveInfo(data){
var buffer = xlsx.build([{name: "mySheetName", data: data}]);
fs.writeFileSync("myFile.xlsx", buffer, 'binary');
console.log('excel保存成功');
}
Voici le diagramme de résultats et la séquence d'exécution du code :
générateur
async
promesse
L'ensemble de votre processus est asynchrone et vous ne voyez aucune signification à la synchronisation. Je pense que vous ne comprenez peut-être pas ce qu'est l'asynchrone.
Async/await est basé sur Promise et Superagent lui-même prend en charge Promise. Vous pouvez utiliser async/await directement.
http://visionmedia.github.io/...
http://www.ruanyifeng.com/blo...
Ensuite, il ne vous reste plus qu'à mettre
http.get()
换成superagent.get()
.En général, les gens n’ont pas la patience de lire la logique métier des autres.
Comme mentionné ci-dessus, Async/await est basé sur Promise. Si l'interface API de la bibliothèque tierce que vous appelez ne renvoie pas d'objet de promesse, si vous souhaitez utiliser Async/await, vous ne pouvez créer un nouvel objet de promesse que sur à chaque étape. C'est en fait très difficile à écrire. Bien sûr, ce serait très pratique s'il pouvait renvoyer un objet promis.
Ce qui suit est écrit en utilisant l'événement du module core du nœud sans promesses, pour votre référence :
Peut utiliser Node8
util.promisify
, ou Bluebird, etc. changez la fonction de style de rappel Node en une fonction de style Promise, puis vous pouvez utiliserasync/await
pour écrire du code.Le code lui-même est toujours un appel asynchrone, mais la méthode d'écriture semble synchrone. Par conséquent, vous devez toujours faire attention à la structure du processus lors de l’écriture, en particulier lors de l’écriture de boucles. Le code est trop long, j'ai donc écrit un petit exemple pour illustrer