午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

node.js - 用node做爬蟲(chóng),循環(huán)模擬接口獲取數(shù)據(jù),async/await怎么做到同步操作,控制流程?

瀏覽:268日期:2024-07-12 11:19:34

問(wèn)題描述

目前的思路如下:1.獲取分類下所有的標(biāo)簽頁(yè)面url,2.循環(huán)抓取頁(yè)面中抓取當(dāng)前標(biāo)簽頁(yè)獲取json的api地址,3.抓取當(dāng)前標(biāo)簽的商品列表,4.抓取當(dāng)前標(biāo)簽的分頁(yè)加載中的商品。

但是現(xiàn)在做到的是,第二步開(kāi)始,未等到2-4執(zhí)行完畢再循環(huán)下一個(gè),有嘗試用async/await,但是未實(shí)現(xiàn)流程控制。此處求教。

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(’分類數(shù)據(jù)請(qǐng)求失敗’); } else {console.log(’分類數(shù)據(jù)請(qǐng)求成功’);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(’分類數(shù)據(jù)為空’);}// 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 + ’頁(yè)面數(shù)據(jù)’); var reg = /goodsUrl = '(.+)'/; var apiUrl = reg.exec(html); getGoodsJson(apiUrl[1],pageIndex); }); }).on(’error’,function(){ console.log(’獲取html出錯(cuò)!!’); });}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 + ’頁(yè)請(qǐng)求失敗’); } else {console.log(’第’ + pageIndex + ’頁(yè)請(qǐng)求成功’);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 + ’rn’; }); pageIndex = parseInt(pageIndex) + 1; setTimeout(function(){ getGoodsJson(url,pageIndex); },200);} else { console.log(’數(shù)據(jù)已加載完畢’); 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保存成功’);}

下面是結(jié)果圖示及代碼執(zhí)行順序:

node.js - 用node做爬蟲(chóng),循環(huán)模擬接口獲取數(shù)據(jù),async/await怎么做到同步操作,控制流程?

node.js - 用node做爬蟲(chóng),循環(huán)模擬接口獲取數(shù)據(jù),async/await怎么做到同步操作,控制流程?

問(wèn)題解答

回答1:

generatorasyncpromise

回答2:

你這整個(gè)過(guò)程都是異步的,沒(méi)看出一點(diǎn)同步的意思。我覺(jué)得你可能沒(méi)有理解什么是異步。

Async/await 是建立在 Promise 基礎(chǔ)上的,而 Superagent 本身是支持 Promise 的,你可以直接用 async/await。

async function() { try { const result = await superagent.get(url); console.log(result.headers); console.log(result.body); } catch (error) { console.error(error); }}

http://visionmedia.github.io/...

http://www.ruanyifeng.com/blo...

然后你需要的就是把 http.get() 換成 superagent.get()。

回答3:

一般他人的業(yè)務(wù)邏輯都沒(méi)什么耐性能看下去。

如樓上所言,Async/await 是建立在 Promise 基礎(chǔ)上,如果你調(diào)用的第三方庫(kù)的API接口沒(méi)有返回promise對(duì)象的話,想用Async/await 你只能自己每一步都新建一個(gè)promise對(duì)象,這樣其實(shí)寫(xiě)起來(lái)也很麻煩,當(dāng)然如果能返回promise對(duì)象的話就很方便。

以下不用promise 用node核心模塊event寫(xiě)的,供你參考一下:

const EventEmitter = require(’events’);class MyEmitter extends EventEmitter {}const myEmitter = new MyEmitter();myEmitter.on(’step1’, (m) => { //第一步 //業(yè)務(wù)邏輯處理得到結(jié)果result1 //判斷是否觸發(fā)下一步,如有需要將這步的結(jié)果傳給下一步 myEmitter.emit(’step2’, result1); });myEmitter.on(’step2’, (result1) => { //第二步 //業(yè)務(wù)邏輯處理得到結(jié)果result2 //判斷是否觸發(fā)下一步,如有需要將這步的結(jié)果傳給下一步 myEmitter.emit(’step3’, result2);});myEmitter.on(’step3’, (result2) => { //以此類推});myEmitter.emit(’step1’, urls);回答4:

可以使用 Node8 的 util.promisify,或者 Bluebird 等把 Node 回調(diào)形式的函數(shù)改成 Promise 風(fēng)格的函數(shù),然后就可以使用 async/await 來(lái)寫(xiě)代碼。

代碼本身還是異步調(diào)用,只是寫(xiě)法看起來(lái)像是同步的。所以在寫(xiě)的時(shí)候還是要注意流程結(jié)構(gòu),尤其是在寫(xiě)循環(huán)的時(shí)候。代的代碼太長(zhǎng),所以我寫(xiě)個(gè)小例子來(lái)說(shuō)明

async function remoteCall() { // do something}list = []; // 假設(shè)是很多數(shù)據(jù)async function process() { // 這種寫(xiě)法必須要一個(gè) remoteCall 完成之后才進(jìn)行另一個(gè) for (let i = 0; i < list.length; i++) {await remoteCall(); } doAfter();}async function process2() { // 這種寫(xiě)法沒(méi)法 await list.forEach(function(t) {remoteCall(); });}async function process3() { // 這種寫(xiě)法 doAfter 一早就會(huì)執(zhí)行 list.forEach(async function(t) {await remoteCall(); }); // 它可能會(huì)在 remoteCall() 之前 doAfter();}async function process4() { // 這種寫(xiě)法必須要全部 remoteCall 成功才能進(jìn)行到 doAfter // remoteCall返回的 promise 如果 reject 會(huì)拋異常 var promises = list.map(t => remoteCall()); await Promise.all(promises); doAfter();}

主站蜘蛛池模板: 亚洲香蕉中文网 | 97超碰免费在线观看 | 成人国产精品免费观看 | 国产专区av | 性巴克成人免费网站 | 成人深夜福利视频 | 四虎国产精品永久免费观看视频 | 亚洲精品123区 | 日韩精品一区二区三区中文在线 | 国产精品成av人在线视午夜片 | 鲁大师影院入口在线观看 | 免费成人小视频 | www.xxav | 日韩专区在线 | 69精品久久久久久 | 岛国裸体写真hd在线 | 国产精品成人国产乱一区 | 久久久久久久91 | 午夜影院视频 | 国产少妇精品 | 日本一区二区精品视频 | 亚洲黄色影院 | 久久精品国产精品 | 国产一级片免费 | 国产精品视频在线观看免费 | 日韩人妻毛片 | 国产视频一 | 免费一级特黄特色大片 | 国产精品国产精品国产 | 日韩免费视频一区二区 | 欧美日韩中文字幕视频 | 婷婷色中文字幕 | 一区二区三区有限公司 | 欧美自拍视频 | 亚洲精品福利视频 | 久久久国产精品一区二区三区 | 99热在线观看 | 成人午夜高清 | 天天舔天天干 | 成人在线免费看片 | 五月婷婷六月天 |