木偶尝试加载延迟加载的图像失败

时间:2018-07-26 14:18:37

标签: javascript node.js puppeteer

我已经编写了一个名为puppeteer-screenshots的小npm程序包,该程序包是Google Puppeteer的包装,并试图简化网站截图的工作。现在,我正在尝试为其添加其他功能,即能够加载延迟加载的图像。这是到目前为止我得到的代码:

const puppeteer = require('puppeteer');
const argum = require('argum');

var Screenshot = function(options) {
    var config;

    if (options === undefined)
    {
        config = {
            url:            argum.get('--url', true, false),
            path:           argum.get('--path', false, 'image.png'),
            viewportWidth:  parseInt(argum.get('--viewportWidth', false, 1280)),
            viewportHeight: parseInt(argum.get('--viewportHeight', false, 768)),
            mobile:         argum.get('--mobile', false, false),
            userAgent:      argum.get('--userAgent', false, false),
            pdf:            argum.get('--pdf', false, false),
            mediaTypePrint: argum.get('--mediaTypePrint', false, false),
            lazyLoad:       argum.get('--lazyLoad', false, false),
            delay:          parseInt(argum.get('--delay', false, false)),
        };
    }
    else
    {
        config = {
            url:            argum.object(options, 'url', true, false),
            path:           argum.object(options, 'path', false, 'image.png'),
            viewportWidth:  parseInt(argum.object(options, 'viewportWidth', false, 1280)),
            viewportHeight: parseInt(argum.object(options, 'viewportHeight', false, 768)),
            mobile:         argum.object(options, 'mobile', false, false),
            userAgent:      argum.object(options, 'userAgent', false, false),
            pdf:            argum.object(options, 'pdf', false, false),
            mediaTypePrint: argum.object(options, 'mediaTypePrint', false, false),
            lazyLoad:       argum.object(options, 'lazyLoad', false, false),
            delay:          parseInt(argum.object(options, 'delay', false, false)),
        };
    }

    return (async function() {

        const browser = await puppeteer.launch({
            args: ['--lang=en-US,en']
        });
        const page = await browser.newPage();

        // set the media type
        if (config.mediaTypePrint)
        {
            await page.emulateMedia('print');
        }
        else
        {
            await page.emulateMedia('screen');
        }

        // set the user agent if one is provided
        if (config.userAgent)
        {
            await page.setUserAgent(config.userAgent);
        }

        if (config.mobile)
        {
            // set user agent to be as Chrome 60 for Android
            await page.setUserAgent('Mozilla/5.0 (Linux; Android 5.1; XT1039 Build/LPBS23.13-17.6-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36');
        }

        await page.goto(config.url, {"waitUntil" : "networkidle0", "timeout" : 45000}).catch(function(err) {
            console.log('Error while opening page.', err);
            process.exit(1);
        });

        await page.setViewport({width: config.viewportWidth, height: config.viewportHeight});

        if (config.mobile)
        {
            // set mobile viewport
            await page.setViewport({width: 320, height: 480});
        }
        else
        {
            await page.setViewport({width: parseInt(config.viewportWidth), height: parseInt(config.viewportHeight)}); // set view port size
        }

        async function requestFinished(request) {
            inflightRequests = Math.max(inflightRequests - 1, 0);

            if (inflightRequests)
            {
                return false;
            }
            else
            {
                if (config.pdf)
                {
                    // save pdf
                    await page.pdf({path: config.path, printBackground: true, displayHeaderFooter: true});
                }
                else
                {
                    // save screenshot
                    await page.screenshot({path: config.path, fullPage: true});
                }
            }
        }

        let inflightRequests = 0;

        // attempt to load lazy loaded images
        if (config.lazyLoad)
        {
            // count all requests that are going to be made
            page.on('request', request => {
                ++inflightRequests;
            });

            await page.on('requestfinished', requestFinished);
            await page.on('requestfailed', requestFinished);

            var maxScroll = await page.evaluate(function() {
                return Promise.resolve(Math.max( document.body.scrollHeight, document.body.offsetHeight,
                        document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight ) - window.innerHeight);
            }).catch(function(err) {
                console.log('Lazy load failed due to an error while getting the scroll height.', err);
                process.exit(1);
            });

            var fullScrolls = Math.floor(maxScroll / config.viewportHeight); // how many times full scroll needs to be done
            var lastScroll = maxScroll % config.viewportHeight; // amount left to get to the bottom of the page after doing the full scrolls

            // do full scrolls if there is any
            for (var i = 1; i <= fullScrolls; i++)
            {
                await page.evaluate(function (i, viewportHeight) {
                    return Promise.resolve(window.scrollTo(0, i*viewportHeight));
                }, i, config.viewportHeight).catch(function(err) {
                    console.log('Promise rejected while scrolling for lazy load images.', err);
                    process.exit(1);
                });
            }

            // do last scroll if there is any
            if (lastScroll > 0)
            {
                await page.evaluate(function (maxScroll) {
                    return Promise.resolve(window.scrollTo(0, maxScroll + 25));
                }, maxScroll).catch(function(err) {
                    console.log('Promise rejected while last scrolling for lazy load images.', err);
                    process.exit(1);
                });
            }
        }

        await requestFinished();

        browser.close();
    })()
};

exports.init = function () {
    return new Screenshot();
};

exports.screenshot = function (options) {
    return new Screenshot(options);
};

惰性加载部分从第106行开始,到第151行结束。

问题是当我跑步时:

node puppeteer-screenshots-init.js --url=https://digg.com --path=digg.png --lazyLoad=true

我没有收到任何错误,但截图从未保存。

在第116-117行,await是正确的解决方法吗?

0 个答案:

没有答案