puppeteer 打开网页出错

开始打开网页
2021-12-22T09:32:19.799Z  [verbose] 访问url次数 1 
2021-12-22T09:32:32.340Z  [verbose] 标签页 3
2021-12-22T09:33:09.763Z  [verbose] 浏览器错误 { Error: Protocol error (Runtime.callFunctionOn): Target closed.
    at Promise (/code/node_modules/puppeteer/lib/Connection.js:183:56)
    at Promise (null:null:null)
    at send (/code/node_modules/puppeteer/lib/Connection.js:182:12)
    at _evaluateInternal (/code/node_modules/puppeteer/lib/ExecutionContext.js:107:44)
    at evaluateHandle (/code/node_modules/puppeteer/lib/ExecutionContext.js:57:17)
    at (/code/node_modules/puppeteer/lib/helper.js:112:23)
    at rerun (/code/node_modules/puppeteer/lib/DOMWorld.js:570:65)
    at _tickCallback (internal/process/next_tick.js:68:7)
  message: 'Protocol error (Runtime.callFunctionOn): Target closed.' }
2021-12-22T09:33:09.764Z  [error] (node:23) UnhandledPromiseRejectionWarning: Error: Protocol error (Network.getCookies): Session closed. Most likely the page has been closed.
    at send (/code/node_modules/puppeteer/lib/Connection.js:180:29)
    at cookies (/code/node_modules/puppeteer/lib/Page.js:382:32)
    at (/code/node_modules/puppeteer/lib/helper.js:112:23)
    at Promise (/code/aicard-event.js:367:28)
2021-12-22T09:33:09.764Z  [error] (node:23) 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: 2)
2021-12-22T09:33:09.764Z  [error] (node:23) [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.
FC Invoke End RequestId: , Error: Function timed out after 120 seconds (maxMemoryUsage: 0MB)

我这块在第一次打开页面的时候waitForFunction报错提示超时,于是我会再重试一次,这个时候waitForFunction就会报Protocol error (Runtime.callFunctionOn): Target closed.,这个问题我十次里面会遇到一两次,想问问这个是为啥啊,我中间url啥的都没改,就只是重新再page.goto一次,为什么会提示这个错误呢。

还有一个问题,这个是我这个方法的结构,我上面waitForFunction报错之后进入catch,在这里面获取cookie,但是目标关闭导致失败,这个时候什么会提示后面的错误,我想问问我这个不是写了reject吗,完了在调用toPDF时也写了.then().catch(),请问这个正确的写法该是怎样的呢

function toPDF() {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < 2; i++) {
            try {
                //打开页面生成pdf
                resolve()
            } catch (e) {
                // 获取cookie
            }

        }
        reject(error)
    })
}

ps

function convertToPDF(url, context) {
    // 生成browser
    return new Promise(async (resolve, reject) => {
        let browser
        for (let i = 0; i < 2; i++) {
            console.log('开始生成浏览器和页面');
            let page
            let nowTime
            try {
                if (!browser) {
                    browser = await puppeteer.launch({
                        headless: true,
                        ignoreHTTPSErrors: true,
                        args: [
                            '--no-sandbox',
                            '--disable-setuid-sandbox',
                            '--disable-dev-shm-usage',
                        ],
                        executablePath: '/mnt/fun/fun/local-chromium/Linux-706915/chrome-linux/chrome'
                    })

                }
                page = await browser.newPage();

                //将超时时间设置成无限
                page.setDefaultTimeout(0);
                page.setDefaultNavigationTimeout(0);      

                console.log('开始打开网页');

                for (let urlNumber = 1; urlNumber < 6; urlNumber++) {
                    try {
                        console.log('访问url次数', urlNumber, ':', url)
                        // 等待网页所有请求结束
                        nowTime = new Date().getTime() / 1000
                        await page.goto(url, {waitUntil: 'networkidle0'});

                        break
                    } catch (e) {
                        console.log('打开url错误开始重试')
                        console.log(e)
                        if (urlNumber >= 5) {
                            console.log('打开url失败')
                        }
                    }
                }

                //设置监控
                const tags = browser.pages()
                console.log('标签页', (await tags).length)

                // 等网页加载成功,超时时间45s
                const watchDog = page.waitForFunction('window.status == "loaded"', {timeout: 45 * 1000});
                await watchDog

                //检查是否生成失败
                let error = null;
                await page.cookies().then(cookies => {
                    console.log('是否成功');

                    for (let cookie of cookies) {
                        if (cookie.name === 'errorMessage') {
                            error = cookie.value;
                            break;
                        } else if (cookie.name.indexOf('debugMsg') >= 0) {
                            console.log(JSON.stringify(cookie.value));
                        }
                    }
                })
                error = error === null ? null : JSON.parse(error);

                //如果失败
                if (error !== null && error.errorType === 0) {
                    console.log('失败123');

                    console.log('失败', JSON.stringify(error));

                    // 关闭browser
                    await browser.close();
                }

                //如果成功
                else {
                    console.log('生成pdf');

                    // 生成pdf
                    await page.pdf({
                        path: outputFile,
                        format: 'A4',
                        printBackground: true,
                        margin: {top: 0, right: 0, bottom: 0, left: 0},
                        preferCSSPageSize: true
                    });

                    // 关闭browser
                    await browser.close();
                    resolve(outputFile);
                }
                break
            } catch (e) {
                console.log('浏览器错误', e)
                await page.cookies(url).then(cookies => {
                    cookies.forEach(cookie => {
                        console.log(cookie.name, Number(cookie.value) - nowTime);
                    })
                })
            }
        }
        reject('pdf错误')
    })

}
阅读 5.9k
1 个回答

试试这个代码:

function convertToPDF(url, context) {
    // 生成browser
    return new Promise(async (resolve, reject) => {
        let browser
        for (let i = 0; i < 2; i++) {
            console.log('开始生成浏览器和页面');
            let page
            let nowTime
            try {
                if (!browser) {
                    browser = await puppeteer.launch({
                        headless: true,
                        ignoreHTTPSErrors: true,
                        args: [
                            '--no-sandbox',
                            '--disable-setuid-sandbox',
                            '--disable-dev-shm-usage',
                        ],
                        executablePath: '/mnt/fun/fun/local-chromium/Linux-706915/chrome-linux/chrome'
                    })

                }
                page = await browser.newPage();

                //将超时时间设置成无限
                page.setDefaultTimeout(0);
                page.setDefaultNavigationTimeout(0);      

                console.log('开始打开网页');

                for (let urlNumber = 1; urlNumber < 6; urlNumber++) {
                    try {
                        console.log('访问url次数', urlNumber, ':', url)
                        // 等待网页所有请求结束
                        nowTime = new Date().getTime() / 1000
                        await page.goto(url, {waitUntil: 'networkidle0'});

                        break
                    } catch (e) {
                        console.log('打开url错误开始重试')
                        console.log(e)
                        if (urlNumber >= 5) {
                            console.log('打开url失败')
                        }
                    }
                }

                //设置监控
                const tags = await browser.pages()
                console.log('标签页', tags.length)

                // 等网页加载成功,超时时间45s
                const watchDog = await page.waitForFunction('window.status == "loaded"', {timeout: 45 * 1000});

                //检查是否生成失败
                let error = null;

                try {
                    let cookies = await page.cookies();
                    for (let cookie of cookies) {
                        if (cookie.name === 'errorMessage') {
                            error = cookie.value;
                            break;
                        } else if (cookie.name.indexOf('debugMsg') >= 0) {
                            console.log(JSON.stringify(cookie.value));
                        }
                    }
                    error = error === null ? null : JSON.parse(error);

                    //如果失败
                    if (error !== null && error.errorType === 0) {
                        console.log('失败123');

                        console.log('失败', JSON.stringify(error));

                        // 关闭browser
                        await browser.close();
                    }else{
                        
                        console.log('生成pdf');
                        // 生成pdf
                        await page.pdf({
                            path: outputFile,
                            format: 'A4',
                            printBackground: true,
                            margin: {top: 0, right: 0, bottom: 0, left: 0},
                            preferCSSPageSize: true
                        });
    
                        // 关闭browser
                        await browser.close();
                        resolve(outputFile);
                    }

                } catch (e) {
                    console.log('cookies', e)
                }

                break
            } catch (e) {
                console.log('浏览器错误', e)
                await page.cookies(url).then(cookies => {
                    cookies.forEach(cookie => {
                        console.log(cookie.name, Number(cookie.value) - nowTime);
                    })
                })
            }
        }
        reject('pdf错误')
    })

}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题