Die aktuelle Idee lautet wie folgt: 1. Alle Tag-Seiten-URLs unter der Kategorie abrufen, 2. Durch die Crawling-Seite blättern, um die aktuelle Tag-Seite abzurufen und die JSON-API-Adresse zu erhalten, 3. Die Produktliste des aktuellen Tags abrufen , 4. Schnappen Sie sich die aktuell geladenen Produkte auf Seiten mit Registerkarten.
Aber was jetzt gemacht wird, ist, dass zu Beginn des zweiten Schritts nicht gewartet wird, bis 2-4 abgeschlossen ist, bevor mit dem nächsten Schritt begonnen wird. Ich habe versucht, async/await zu verwenden, aber die Prozesssteuerung wurde nicht implementiert. Bitte hier um Rat.
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保存成功'); }
Das Folgende ist das Ergebnisdiagramm und die Codeausführungssequenz:
generator
async
promise
你这整个过程都是异步的,没看出一点同步的意思。我觉得你可能没有理解什么是异步。
Async/await 是建立在 Promise 基础上的,而 Superagent 本身是支持 Promise 的,你可以直接用 async/await。
http://visionmedia.github.io/...
http://www.ruanyifeng.com/blo...
然后你需要的就是把
http.get()
换成superagent.get()
。一般他人的业务逻辑都没什么耐性能看下去。
如楼上所言,Async/await 是建立在 Promise 基础上,如果你调用的第三方库的API接口没有返回promise对象的话,想用Async/await 你只能自己每一步都新建一个promise对象,这样其实写起来也很麻烦,当然如果能返回promise对象的话就很方便。
以下不用promise 用node核心模块event写的,供你参考一下:
可以使用 Node8 的
util.promisify
,或者 Bluebird 等把 Node 回调形式的函数改成 Promise 风格的函数,然后就可以使用async/await
来写代码。代码本身还是异步调用,只是写法看起来像是同步的。所以在写的时候还是要注意流程结构,尤其是在写循环的时候。代的代码太长,所以我写个小例子来说明