Pobieranie obrazów za pomocą węzła.js [zamknięte]

zamknięte . To pytanie musi być bardziej skoncentrowane . Obecnie nie przyjmuje odpowiedzi.

Chcesz poprawić to pytanie? Update the question so it edytując ten post.

Zamknięte 2 lata temu .

Popraw to pytanie

Próbuję napisać skrypt do pobierania obrazów za pomocą węzła.js. To jest to co mam do tej pory:

var maxLength = 10 // 10mb
var download = function(uri, callback) {
  http.request(uri)
    .on('response', function(res) {
      if (res.headers['content-length'] > maxLength*1024*1024) {
        callback(new Error('Image too large.'))
      } else if (!~[200, 304].indexOf(res.statusCode)) {
        callback(new Error('Received an invalid status code.'))
      } else if (!res.headers['content-type'].match(/image/)) {
        callback(new Error('Not an image.'))
      } else {
        var body = ''
        res.setEncoding('binary')
        res
          .on('error', function(err) {
            callback(err)
          })
          .on('data', function(chunk) {
            body += chunk
          })
          .on('end', function() {
            // What about Windows?!
            var path = '/tmp/' + Math.random().toString().split('.').pop()
            fs.writeFile(path, body, 'binary', function(err) {
              callback(err, path)
            })
          })
      }
    })
    .on('error', function(err) {
      callback(err)
    })
    .end();
}
[[7]}ja jednak chcę, aby było to bardziej wytrzymałe:
  1. są biblioteki, które robią to i robią to lepiej?
  2. czy jest szansa, że nagłówki odpowiedzi kłamią (o długości, o typie treści)?
  3. czy są jakieś inne kody statusu, którymi powinienem się przejmować? Czy powinienem zawracać sobie głowę przekierowaniami?
  4. chyba gdzieś czytałem, że kodowanie będzie przestarzałe. Co mam wtedy zrobić?
  5. Jak mogę to uruchomić w systemie windows?
  6. jakieś inne sposoby na ulepszenie tego skryptu?

Dlaczego: dla funkcji podobnej do imgur gdzie użytkownicy mogą dać mi adres URL, pobieram Ten obraz, i ponownie obraz w wielu rozmiarach.

Author: Shanil Arjuna, 2012-10-05

7 answers

Sugerowałbym użycie modułu request . Pobieranie pliku jest tak proste, jak poniższy kod:

var fs = require('fs'),
    request = require('request');

var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    console.log('content-type:', res.headers['content-type']);
    console.log('content-length:', res.headers['content-length']);

    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
  });
};

download('https://www.google.com/images/srpr/logo3w.png', 'google.png', function(){
  console.log('done');
});
 420
Author: Cezary Wojtkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 10:11:07

Napotkałem ten problem kilka dni temu, dla czystej odpowiedzi NodeJS sugerowałbym użycie strumienia do scalania kawałków razem.

var http = require('http'),                                                
    Stream = require('stream').Transform,                                  
    fs = require('fs');                                                    

var url = 'http://www.google.com/images/srpr/logo11w.png';                    

http.request(url, function(response) {                                        
  var data = new Stream();                                                    

  response.on('data', function(chunk) {                                       
    data.push(chunk);                                                         
  });                                                                         

  response.on('end', function() {                                             
    fs.writeFileSync('image.png', data.read());                               
  });                                                                         
}).end();

Najnowsze wersje węzłów nie będą działać dobrze z łańcuchami binarnymi, więc łączenie fragmentów z łańcuchami nie jest dobrym pomysłem podczas pracy z danymi binarnymi.

* Należy zachować ostrożność podczas używania ' data.read ()', opróżni strumień dla następnej operacji ' read ()'. Jeśli chcesz użyć go więcej niż raz, przechowuj go gdzieś.

 37
Author: Nihey Takizawa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-19 13:46:44

Możesz użyć Axios (klient HTTP oparty na promise dla węzła.js) do pobierania obrazów w wybranej kolejności w środowisku asynchronicznym :

npm i axios

Następnie możesz użyć następującego podstawowego przykładu, aby rozpocząć pobieranie obrazów:

const fs = require('fs');
const axios = require('axios');

/* ============================================================
  Function: Download Image
============================================================ */

const download_image = (url, image_path) =>
  axios({
    url,
    responseType: 'stream',
  }).then(
    response =>
      new Promise((resolve, reject) => {
        response.data
          .pipe(fs.createWriteStream(image_path))
          .on('finish', () => resolve())
          .on('error', e => reject(e));
      }),
  );

/* ============================================================
  Download Images in Order
============================================================ */

(async () => {
  let example_image_1 = await download_image('https://example.com/test-1.png', 'example-1.png');

  console.log(example_image_1.status); // true
  console.log(example_image_1.error); // ''

  let example_image_2 = await download_image('https://example.com/does-not-exist.png', 'example-2.png');

  console.log(example_image_2.status); // false
  console.log(example_image_2.error); // 'Error: Request failed with status code 404'

  let example_image_3 = await download_image('https://example.com/test-3.png', 'example-3.png');

  console.log(example_image_3.status); // true
  console.log(example_image_3.error); // ''
})();
 36
Author: Grant Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 18:53:04

Jeśli chcesz pobrać postęp, spróbuj tego:

var fs = require('fs');
var request = require('request');
var progress = require('request-progress');

module.exports = function (uri, path, onProgress, onResponse, onError, onEnd) {
    progress(request(uri))
    .on('progress', onProgress)
    .on('response', onResponse)
    .on('error', onError)
    .on('end', onEnd)
    .pipe(fs.createWriteStream(path))
};

Jak używać:

  var download = require('../lib/download');
  download("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png", "~/download/logo.png", function (state) {
            console.log("progress", state);
        }, function (response) {
            console.log("status code", response.statusCode);
        }, function (error) {
            console.log("error", error);
        }, function () {
            console.log("done");
        });

Uwaga: powinieneś zainstalować moduły request I request-progress używając:

npm install request request-progress --save
 10
Author: Fareed Alnamrouti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 17:36:39
var fs = require('fs'),
http = require('http'),
https = require('https');

var Stream = require('stream').Transform;

var downloadImageToUrl = (url, filename, callback) => {

    var client = http;
    if (url.toString().indexOf("https") === 0){
      client = https;
     }

    client.request(url, function(response) {                                        
      var data = new Stream();                                                    

      response.on('data', function(chunk) {                                       
         data.push(chunk);                                                         
      });                                                                         

      response.on('end', function() {                                             
         fs.writeFileSync(filename, data.read());                               
      });                                                                         
   }).end();
};

downloadImageToUrl('https://www.google.com/images/srpr/logo11w.png', 'public/uploads/users/abc.jpg');
 6
Author: Chandan Chhajer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 16:59:38

To rozszerzenie do odpowiedzi Cezarego. Jeśli chcesz pobrać go do określonego katalogu, użyj tego. Użyj również const zamiast var. Tak jest bezpiecznie.

const fs = require('fs');
const request = require('request');
var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){    
    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
  });
};

download('https://www.google.com/images/srpr/logo3w.png', './images/google.png', function(){
  console.log('done');
});
 6
Author: Ahsan Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 20:50:28

Bazując na powyższym, jeśli ktoś musi poradzić sobie z błędami w strumieniu zapisu/odczytu, użyłem tej wersji. Zwróć uwagę na stream.read() w przypadku błędu zapisu, jest to wymagane, abyśmy mogli zakończyć odczyt i wyzwolić close na strumieniu odczytu.

var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    if (err) callback(err, filename);
    else {
        var stream = request(uri);
        stream.pipe(
            fs.createWriteStream(filename)
                .on('error', function(err){
                    callback(error, filename);
                    stream.read();
                })
            )
        .on('close', function() {
            callback(null, filename);
        });
    }
  });
};
 4
Author: VladFr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-02 14:08:25