【问题标题】:How to stop NodeJS script from crashing when timeout exceeded超时时如何阻止NodeJS脚本崩溃
【发布时间】:2019-09-10 23:57:15
【问题描述】:

您可以在下面找到发生的错误。

我正在尝试使用 NodeJS 和 puppeteer 抓取网站的内容。有时代码会因错误超时而停止。有没有办法,如果超过页面加载的超时,我可以运行一个函数来重新加载页面或让脚本等待几秒钟,然后重新加载页面,直到它正确获取数据,而不会崩溃? 如果是这样,我将如何实施?

谢谢。

(node:8300) UnhandledPromiseRejectionWarning: TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded
    at Promise.then (C:\Users\danie\node_modules\puppeteer\lib\LifecycleWatcher.js:143:21)
  -- ASYNC --
    at Frame.<anonymous> (C:\Users\danie\node_modules\puppeteer\lib\helper.js:108:27)
    at Page.goto (C:\Users\danie\node_modules\puppeteer\lib\Page.js:656:49)
    at Page.<anonymous> (C:\Users\danie\node_modules\puppeteer\lib\helper.js:109:23)
    at scrape (C:\Users\danie\Documents\Node Projects\p-download.js:23:14)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:8300) 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: 1)
(node:8300) [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.

我的代码:

const puppeteer = require('puppeteer');

let scrape = async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();

    await page.setRequestInterception(true);    
    page.on('request', (req) => {
        if(req.resourceType() == 'stylesheet' || req.resourceType() == 'script' || req.resourceType() == 'font' || req.resourceType() == 'media' || req.resourceType() == 'image'){
            req.abort();
        }
        else {
            req.continue();
        }
    }); //Disables loading CSS, images and scripts

    for(i=0; i<5000; i++){
        await page.goto('https://website.com/' + i);
        let result = await page.evaluate(() => {
            var result = '';
            for (i=1; i<=10; i++){
                result += document.getElementsByTagName('td')[i].innerText;
                result += ',';
            }
            result += '\n';
            return result;
        });
    }
}
scrape();

【问题讨论】:

    标签: javascript node.js timeout settimeout puppeteer


    【解决方案1】:

    将你的代码放在 try/catch 块中以避免崩溃...我会将循环代码移到另一个函数中

    for(i=0; i<5000; i++){
        result = await open_page(page , i );
    }
    
    
    async function open_page(page , i ){
        try {
                await page.goto('https://website.com/' + i);
                let result = await page.evaluate(() => {
                    var result = '';
                    for (i=1; i<=10; i++){
                        result += document.getElementsByTagName('td')[i].innerText;
                        result += ',';
                    }
                    result += '\n';
                    return result;
                });
    
    
                return {stat:1 , result : result } ;
    
        }
        catch(e){
            return {stat:0 , error : e } ;
        }
    
    }
    

    【讨论】:

    • 谢谢。在 catch(e) 之后,我为错误添加了 console.log,然后 i-- 再次重复该过程。
    • @DanielRika 你知道当你写一个机器人来废弃数据时,你必须避免卡在一个链接上……比如如果site.com/100由于某种原因没有打开你会打电话给这个地址一遍又一遍,而其他号码永远不会被呼叫,您必须将链接放在某种队列中
    • 是的,我明白了,但在这种情况下,每个链接都可以正常工作,并且到目前为止它运行良好。唯一的问题是它有时很慢。不过感谢您的帮助:)
    • @DanielRika 你可以同时在多个标签页上打开多个链接
    • 这很有趣。您能否参考任何代码或脚本,让我了解它的工作原理?
    猜你喜欢
    • 2017-01-26
    • 2015-08-24
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多