NodeJS Puppeteer setDownloadBehavior проблема - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь установить собственный путь для загрузки, но Chrome все равно помещает файлы в типичную папку Downloads.

const puppeteer = require('puppeteer');

(async () => {
   const browser = await puppeteer.launch({
      executablePath: 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe',
      defaultViewport: {
          width: 1920,
          height: 1080
      },
      headless: false,
      userDataDir: "./user_data"
   });

   const page = await browser.newPage();

   await page.goto(
     'https://example.com/page-with-the-file-link',
      { waitUntil: 'domcontentloaded' },
   );

   await page._client.send('Page.setDownloadBehavior', {
         behavior: 'allow',
         downloadPath: 'C:/Users/Me/Downloads/custom/folder/'
   });

   console.log('Start downloading');

   await page.click('a.download-btn');

   await page.waitFor(5000);

   console.log('Complete');
   await browser.close();
})();

Таким образом, он игнорирует параметр downloadPath и помещает файл в папку C:/Users/Me/Downloads по умолчанию.

Также он не ждет 5 секунд, он только успевает загрузить файл и выходит сразу после нажатия на ссылку для скачивания.

Start downloading
Complete
(node:51016) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 3 (CLOSED)
    at WebSocket.send (C:\Users\Me\Downloads\puppeteer\node_modules\ws\lib\websocket.js:329:19)
    at WebSocketTransport.send (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\WebSocketTransport.js:60:14)
    at Connection._rawSend (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\Connection.js:86:21)
    at Connection.send (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\Connection.js:72:21)
    at gracefullyCloseChrome (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\Launcher.js:194:20)
    at Browser.close (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\Browser.js:255:31)
    at Browser.<anonymous> (C:\Users\Me\Downloads\puppeteer\node_modules\puppeteer\lib\helper.js:112:23)
    at C:\Users\Me\Downloads\puppeteer\test-download-file.js:97:18
    at <anonymous>
(node:51016) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
(node:51016) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Почему этот скрипт просто закрывается после нажатия на ссылку для скачивания и как это сделать правильно? Есть ли какая-нибудь функция для отслеживания статуса загрузки и отслеживания прогресса?

Любой совет будет оценен, спасибо!

1 Ответ

0 голосов
/ 09 июля 2019

Как обойти это с костылями

enter image description here

1) Мы должны поймать / подождать файл, которыйПо умолчанию будет отображаться 'Downloads' каталог

function checkExistsWithTimeout(filePath, timeout) {
    return new Promise(function (resolve, reject) {

        var timer = setTimeout(function () {
            watcher.close();
            reject(new Error('File did not exists and was not created during the timeout.'));
        }, timeout);

        fs.access(filePath, fs.constants.R_OK, function (err) {
            if (!err) {
                clearTimeout(timer);
                watcher.close();
                resolve();
            }
        });

        var dir = path.dirname(filePath);
        var basename = path.basename(filePath);
        var watcher = fs.watch(dir, function (eventType, filename) {
            if (eventType === 'rename' && filename === basename) {
                clearTimeout(timer);
                watcher.close();
                resolve();
            }
        });
    });
}

Проверять файл на всякий случай (опционально)

function checkFile(path) {
    return new Promise(function (resolve, reject) {
        fs.access(path, fs.F_OK, (err) => {
            if (err) {
                reject(new Error(err));
            }

            //file exists
            console.log('File exists');
            resolve();
        });
    });
}

Перемещать файл везде, где мынеобходимо после завершения загрузки (опционально)

function moveFile(fromPath, toPath) {
    return new Promise(function (resolve, reject) {
        fs.rename(fromPath, toPath, function (err) {
            if (err) {
                reject(new Error('File did not move.'));
                throw err;
            } else {
                console.log('File moved');
                resolve();
            }
        });
    });
}

Пример

const fileName = await page.evaluate(() => {
   return document.querySelector('.download-file-btn').textContent.trim();
});
await page.click('.download-file-btn');
await checkExistsWithTimeout('C:/Users/Me/Downloads/'+fileName, 10000);
await moveFile('C:/Users/Me/Downloads/'+fileName, 'C:/Users/me/Desktop/Videos/'+fileName);

2) Выгрузить файл из URL с использованием пакета 'request'

function download(uri, filename, callback) {
    return new Promise(function (resolve, reject) {
        request.head(uri, function (err, res, body) {
            if (!err && res.statusCode == 200) {
                console.log('content-type:', res.headers['content-type']);
                console.log('content-length:', res.headers['content-length']);

                request(uri)
                .pipe(fs.createWriteStream(filename))
                .on('error', function(response) {
                    console.log(err);
                    reject(new Error(err));
                })
                .on('close', function() {
                    callback();
                    resolve();
                });
            } else {
                reject(new Error(err));
            }
        });
    });
}

Пример

const videoSrc = await page.evaluate(() => {
     return document.querySelector('video.vjs-tech').src;
});

await download(videoSrc, "C:/Users/Me/Downloads/Videos/video.mp4", function() {
   console.log('downloaded');
});

У меня работает без опции 'setDownloadBehavior', иначе не получается.Теперь я могу нажать кнопку «Загрузить» или загрузить файл напрямую с некоторого URL-адреса, просто манипулируя файловой системой с узлом чуть-чуть.

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...