使用node.js从网站下载图像

时间:2017-04-26 20:21:41

标签: javascript node.js

我正在尝试使用节点脚本下载网站上的每个图片。

我写了它并且在大多数情况下它似乎正在工作,但是,它只下载第一张图片。它下载的数量等于网站上的图像数量。

这是我的代码。

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);
    })
});
}

我认为问题出在ripImage()函数的某个地方。如果你们能看到问题并帮助我解决问题,那真的很感激。

谢谢你们。

1 个答案:

答案 0 :(得分:0)

@ Mr.Phoenix是对的,异步库是针对这类事情的。它允许您使用异步函数迭代集合,并在所有异步函数完成时触发回调。工作代码:

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)
    })
  })
}