javascript - 关于node抓取图片,打包,异步循环程序执行顺序的问题
本文介绍了javascript - 关于node抓取图片,打包,异步循环程序执行顺序的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
var request = require('request')
var cheerio = require('cheerio')
var fs = require('fs');
var rand = require('./routes/randm.js')
var eventproxy = require('eventproxy')
var ep = eventproxy()
var async = require('async')
var zipper = require('zip-local')
var cont = 0
var urlarr = ['。。。']//抓的link
var datatext = [];
var j = 0;
var newfolder = rand()
cont = urlarr.length
fs.mkdirSync('./public/result/' + newfolder)
async.mapLimit(urlarr, 1, function (urls, callback) {
startRequest(urls)
function startRequest(urls) {
request(urls, function (error, response, body) {
var $ = cheerio.load(body)
cont += $('.common-productbox-product__image img').length
//遍历下载图片
$('.common-productbox-product__image img').each(function () {
j++
var imgurl = '。。。' + $(this).attr('src').split('?')[0]
var imgname = $(this).attr('title')
downloadPic(imgurl, './public/result/' + newfolder + '/' + imgname + '.jpg', imgname, j)
})
//判断是否有下一页,有的话继续遍历下一页
var nextUrl = $('.next a').attr('href');
if (nextUrl == 'javascript:void(0);' || typeof (nextUrl) == "undefined") {
ep.emit('got_success')
callback(null)
} else if (urls.split("?").length > 1) {
var nextpageurl = urls.split("?")[0] + nextUrl;
// urlarr.splice(i+1,0,nextpageurl)
startRequest(nextpageurl)
} else {
var nextpageurl = urls + nextUrl;
// urlarr.splice(i+1,0,nextpageurl)
startRequest(nextpageurl)
}
console.log(j + '正在爬取' + urls)
//接收'got_success'将图片打包
ep.after('got_success', cont, function () {
console.log('=============================done,countis :' + cont + '======================')
zipper.sync.zip("./public/result/" + newfolder).compress().save("./public/result/" + newfolder + ".zip")
})
})
}
})
var downloadPic = function (src, dest, name, j) {
var writeStream = fs.createWriteStream(dest, {
autoClose: true
})
request(src).pipe(writeStream).on('end', function () {
writeStream.end()
})
writeStream.on('finish', function () {
console.log(j + ':' + name)
ep.emit('got_success')
})
}
做网页爬虫下载图片,我的需求是爬页面的指定的图片,如果有下一页继续调用startRequest抓下一页,最后所有页面都下载完毕后,把他们都一起打包,
现在是有几个问题:
1.没下载完就就执行了ep.after,并且爬了几个页就执行几遍ep.after,我想做成就执行一遍ep.after.
2.貌似程序是先打印:
正在爬取 XX页
一些数据
.
.
.
=============================done,countis :xx======================
正在爬取 XX页
一些数据
.
.
.
=============================done,countis :xx======================
正在爬取 XX页
一些数据
.
.
.
最后导致第三次输出done之后的图片没有压缩进去。
我的程序很乱,感觉异步循环request不知道从何下手了,求高手指教~~拜谢
解决方案
是因为你执行一次startRequest就绑定一次ep.after, 所以最终触发got_success事件的时候, 就一次触发多个回调了吧.
还有, 你最后的下载每一个图片的地方, 都触发一次got_success事件, 这就不可以理解了.
一般代码都会这样写
eventproxy.on('all_done', ()=>{ /* 做最后的处理工作, 例如压缩文件 */ });
function download_page(url) {
request(url, function(page_html) {
/* 处理页面HTML代码, 提取所有图片URL */
var imgs = ['image_url'];
var waits = imgs.map(get_image);
Promise.all(waits).then(function(){
// 图片下载完成, 分析是否有下一页, 有的话继续调用download_page()
if (next_page_url) {
download_page(next_page_url);
} else {
eventproxy.emit('all_done');
}
});
});
}
function get_image(url) {
return new Promise(function(ok, fail){
request(url, function(img) {
// 写入图片内容 img 到对应的文件
// 所有操作完成后, 触发Promise的完成状态
ok();
});
});
}
download_page('page_1_url_string');
这篇关于javascript - 关于node抓取图片,打包,异步循环程序执行顺序的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文