Снимок экрана с URL-адресом с помощью node - async

Вот мой код:

const fs = require('fs');
const screenshot = require('screenshot-stream');
const urlp = require('url');
var urls=[
'https://archive.org/details/8bitrecs',
'http://hackaday.com/',
'http://techcrunch.com/2012/02/16/auraslate-is-an-open-source-android-tablet-for-hackers/',
'http://www.english.illinois.edu/-people-/faculty/debaron/482/482readings/greenfield.html',
'http://sustain.rca.ac.uk/Sustain-Talks'];
urls.forEach(function(url){
    const stream = screenshot(url, '1024x768', {crop: true});
    stream.pipe(fs.createWriteStream(urlp.parse(url).hostname + 'test-1024x768.png')); 
});

Он делает снимки экрана только с последним элементом в URL-адресе. Остальные - изображения с нулевыми байтами. Я думаю, мне нужно выполнять операцию асинхронно, чтобы она не перезаписывала поток каждый раз.

Как бы я это сделал?

ОБНОВИТЬ: Я хочу, чтобы скриншот работал, но ловил ошибки, а не блокировал, если URL-адрес недоступен

ОБНОВИТЬ: https://www.npmjs.com/package/screenshot-promise работал лучше, хотя приведенный ниже код по-прежнему сильно замедляет мой компьютер!

const screenshotPromise = require('screenshot-promise');

...

urls.forEach(function(url) {



const promise = screenshotPromise(url, '1024x768', {crop: true}).then(buf => {
    fs.writeFileSync(urlp.parse(url).hostname + 'test-1024x768.png', buf);
});


promise.then((value) => {
  // value is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.info(value);
});

Где определяется переменная stream?

Janith 17.09.2018 11:20

const stream = screenshot (url, '1024x768', {crop: true});

weaveoftheride 17.09.2018 14:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не смогли добавить сюда ошибку:

events.js:160
throw er; // Unhandled 'error' event ^

Error: Couldn't load url: http://techcrunch.com/2012/02/16/auraslate-is-an-open-source-android-tablet-for-hackers/
at LineStream.byline.on.data
(e:---\node_modules\screenshot-stream\index.js:77:16)
at emitOne (events.js:96:13)
at LineStream.emit (events.js:188:7)

Проблема в том, что модуль screenshot-stream использует PhantomJS, и phantomJS не может перейти на страницу, которая выводит ошибку.

Эта ошибка кажется связанной с этой проблемой: https://github.com/ariya/phantomjs/issues/10460.

Techcrunch.com and Aol.com seem to use web fonts (e.g. "BebasNeue-webfont.ttf") which Qt loads as application fonts. Something may be going wrong there.

Я предлагаю использовать Google Puppeteer, который включает встроенный метод создания снимков экрана: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions

Google puppeteer выглядит, вероятно, более приятным вариантом. Спасибо.

weaveoftheride 17.09.2018 15:03

Код, который я сделал, в итоге сработал:

   const puppeteer = require('puppeteer');
const urlp = require('url');
var URL = require('url-parse');
var urls = [
    'https://archive.org/details/8bitrecs',
    'http://hackaday.com/',
    'http://techcrunch.com/2012/02/16/auraslate-is-an-open-source-android-tablet-for-hackers/',
    'http://www.english.illinois.edu/-people-/faculty/debaron/482/482readings/greenfield.html',
    'http://sustain.rca.ac.uk/Sustain-Talks',
    'https://www.quintessentially.com/',
    'https://www.producthunt.com/tech/ux-project-checklist',
    'https://freedom.press/',
    'http://issuu.com/search?q=vintage+motorcycle',
    'http://www.pocketmod.com/v2/',
    'https://www.metamind.io/',
    'http://nautil.us/blog/chernobyls-hot-mess-the-elephants-foot-is-still-lethal',
    'https://www.instructables.com/id/Tool-Storage-Hacks-or-How-to-Hang-Those-Black-Frid/',
    'https://www.zippi.co.uk/framed-photo-print'
];
var getLocation = function(href) {
    var l = document.createElement("a");
    l.href = href;
    return l;
};
(async() => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    page.waitForNavigation({
        timeout: 40000
    });
    for (let i = 0; i < urls.length; i++) {
        const url = urls[i];
        var url1 = new URL(url);
        try {
            await page.goto(`${url}`);
            await page.screenshot({
                path: 'images/' + url1.hostname + '.png'
            });
        } catch (error) {
            console.info(error.message);
            // await page.close();
            // await browser.close();
            // process.exit(1);
            continue;
        }
    }
})();

Другие вопросы по теме