Estoy tratando de descargar cada imagen en un sitio web usando un script de nodo.
Lo escribí y en su mayor parte parece estar funcionando, sin embargo, solo está descargando la primera imagen. Lo descarga igual a la cantidad de imágenes en el sitio.
Aquí está mi código.
const http = require('http'), cheerio = require('cheerio'), fs = require('fs'); var document = ''; var imageData = ''; http.get('http://www.wikihow.com/Start-a-Blog', function(res){ res.on('data', function(chunk){ document+=chunk; }) res.on('end', function(){ let $ = cheerio.load(document); var array = []; var array = $("img").toArray(); var data = []; array.forEach(function (ele) { if (ele.attribs.src !== undefined) data.push(ele.attribs.src); }) var counter = 0; data.forEach(function (ele) { ripImage(ele, counter); counter ++; }) }) }); function ripImage(ele, counter){ http.get(ele, function(res){ console.log(res); res.setEncoding('binary') res.on('data', function(chunk){ imageData += chunk; }) res.on('end', function(){ //console.log(ele); fs.writeFile("dump/file" + counter + ".jpg", imageData, 'binary', function(err){ if (err) throw err //console.log('File saved.') }); //res.pipe(file); }) }); }Creo que el problema radica en algún lugar de la función ripImage(). Si pueden ver el problema y ayudarme a solucionarlo, sería muy apreciado.
Gracias chicos.
@ Mr.Phoenix tiene razón, la biblioteca asíncrona está diseñada para este tipo de cosas. Le permite iterar sobre una colección con una función asíncrona y activar una devolución de llamada cuando se hayan completado todas las funciones asíncronas. Código de trabajo:
const http = require('http') const cheerio = require('cheerio') const fs = require('fs') const async = require('async') let document = '' http.get('http://www.wikihow.com/Start-a-Blog', (res) => { res.on('data', (chunk) => { document += chunk }) res.on('end', () => { const $ = cheerio.load(document) const data = $('img') .toArray() .filter((ele) => ele.attribs.src) .map((ele) => ele.attribs.src) async.eachOf(data, ripImage, (err) => { if (err) throw err console.log('all done!') }) }) }) function ripImage (ele, i, callback) { http.get(ele, (res) => { let imageData = '' res.setEncoding('binary') res.on('data', (chunk) => { imageData += chunk }) res.on('end', () => { fs.writeFile('./dump/file' + i + '.jpg', imageData, 'binary', callback) }) }) }