Задать вопрос

NODE.JS – парсинг контента. При скачивании изображений получаю битые файлы. Как поправить?

Для парсинга контента, товаров каталога, использую NODE.JS. Написанный парсер работает. Однако, в процессе парсинга получаю битые изображения товаров.
68be99d92b251192865441.jpeg

Сам парсер собирает данные из HTML – кода сайта производителя: названия, описания, цены, характеристики товаров в том числе и ссылки на файлы изображений товаров.
По ссылкам на файлы изображений товаров - прохожу в цикле и скачиваю каждое изображение с помощью функции:
/**     
 * url - ссылка на файл с изображением
 * dir - Директория, папка для скаченного файла
 * prefix - строка для названия файла
 * getString(10) - функция для формирования подстроки из сислучайных символов для уникального названия файла
 */

function getFile(url, dir='images', prefix=''){ 
    //Определяем расширение файла, формируем путь из дирикторий и названия файла   
    let extension = url.slice(url.lastIndexOf('.') + 1);
    dir = `./upload/${dir}`;
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
    let filePath = `${dir}/${prefix}_${getString(10)}.${extension}`;     
    //Функция для скачиванеи файла на диск
    function doRequest(url, filePath) {      
        https.get(url, function(res) {           
            res.on('data', function(data) {                            
                require('fs').createWriteStream(filePath, {flags:'a+'}).write(data);
            });
        });
    }
    //Функция для проверки неаличия скаченного файла на дикске
    async function exists (path) {  
        try {
            await Fs.access(path)
            return true
        } catch {
            return false
        }
    }
    //Скачиваем файл по ссылке  
    doRequest(url, filePath); 
    //Проверяем, если файл скачен на диск возвращаем строку - путь к файлу 
    return exists(filePath) ? filePath : false  
}


Однако часть полученных файлов изображений битые, с артефактами. Возможно, в связи с асинхронностью. Возможно, проблема в логике скрипта.

Как поправить? Что сделать, чтобы получать корректные изображения?
  • Вопрос задан
  • 112 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 1
rqdkmndh
@rqdkmndh
Web-разработчик
const https = require('https');
const fs = require('fs');
const path = require('path');
const { URL } = require('url');

async function downloadFile(url, outputPath) {
    // Парсим URL для получения компонентов
    const parsedUrl = new URL(url);
    
    // Если путь для сохранения не указан, используем имя файла из URL
    if (!outputPath) {
        outputPath = path.basename(parsedUrl.pathname);
    }

    return new Promise((resolve, reject) => {
        const file = fs.createWriteStream(outputPath);
        
        https.get(url, (response) => {
            // Проверяем статус код ответа
            if (response.statusCode !== 200) {
                reject(new Error(`Ошибка загрузки: ${response.statusCode}`));
                return;
            }

            // Получаем общий размер файла для прогресса
            const totalSize = parseInt(response.headers['content-length'], 10);
            let downloadedSize = 0;
            
            response.pipe(file);

            // Опционально: отслеживание прогресса загрузки
            response.on('data', (chunk) => {
                downloadedSize += chunk.length;
                if (totalSize) {
                    const percent = (downloadedSize / totalSize * 100).toFixed(2);
                    console.log(`Загружено: ${percent}%`);
                }
            });

            file.on('finish', () => {
                file.close();
                resolve({ path: outputPath, size: downloadedSize });
            });
        }).on('error', (err) => {
            fs.unlink(outputPath, () => reject(err));
        });

        file.on('error', (err) => {
            fs.unlink(outputPath, () => reject(err));
        });
    });
}

// Пример использования
downloadFile('https://example.com/file.zip', './downloaded-file.zip')
    .then((result) => console.log(`Файл сохранен: ${result.path} (${result.size} байт)`))
    .catch((err) => console.error('Ошибка загрузки:', err));
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы