Node.js 木偶师不断获得超时错误:导航超时超过80000毫秒

Node.js 木偶师不断获得超时错误:导航超时超过80000毫秒,node.js,express,puppeteer,ubuntu-18.04,windows-subsystem-for-linux,Node.js,Express,Puppeteer,Ubuntu 18.04,Windows Subsystem For Linux,我正在尝试刮取作为传递到刮取函数的任何网页,但无论在page.goto()上设置的超时值是多少,我都会收到一个超时错误,如果设置为0,则应用程序会一直等待 const express=require('express'); const cors=需要(“cors”); const MYPORT=process.env.PORT | | 4001; 常量app=express(); const puppeter=require('puppeter'); 使用(express.json()); 应

我正在尝试刮取作为传递到刮取函数的任何网页,但无论在page.goto()上设置的超时值是多少,我都会收到一个超时错误,如果设置为0,则应用程序会一直等待

const express=require('express');
const cors=需要(“cors”);
const MYPORT=process.env.PORT | | 4001;
常量app=express();
const puppeter=require('puppeter');
使用(express.json());
应用程序使用(cors());
常量刮取=异步(url)=>{
变异体;
试一试{
const browser=wait puppeter.launch({
无头:是的,
args:['--无沙盒'],
超时:0
});
console.log(“浏览器启动”);
const page=wait browser.newPage();
console.log(“页面已打开”);
wait page.goto(url,{waitUntil:'load',超时:3*60000});
wait page.waitForSelector('body',{waitUntil:'load'})
console.log(“链接已打开”);
wait page.waitForNavigation({waitUntil:'networkidle2',超时:3*60000});
第页$eval('html',bdy=>{
控制台日志(bdy);
body=bdy.innerHTML;
});
browser.close();
返回体;
}捕捉(错误){
控制台日志(err);
}
};

刮http://google.com');对于脚本的一部分,您已经将等待超时的时间复杂化了一点。我建议作出以下更改:

  • 如果您不确定是什么原因导致超时,则应设置
    headless:false
    ,以便您可以在UI上查看出了什么问题,您可以打开浏览器控制台等
  • 在脚本使用
    waitForSelector
    -s执行您想要的操作之前,不要设置超时。我从你的脚本中删除了它们
  • 如果您对每个网络事件都不感兴趣(尤其是对分析和跟踪请求不感兴趣),但只需要DOM,那么请使用
    waitUntil:'domcontentloaded'
    ,而不是
    load
    或最严格的
    networkidle2
    !在文档中查看它们之间的确切区别:
  • 在等待选择器后,不要等待导航。这就是脚本失败的主要原因:一旦
    出现在DOM中,您要求木偶演员等待导航完成,但此时您没有导航:您已经在页面上了。请记住:
    page.waitForNavigation
    在页面导航到新URL或重新加载时解析。当您运行代码时,它非常有用,因为代码会间接导致页面导航

  • 您的
    页面.eval$
    缺少异步特性,但它应该始终是异步的。无论如何,
    innerHTML
    可以通过:
    wait page.evaluate(el=>el.innerHTML,wait page.$('body'))更简单地检索
  • const scrape=async url=>{
    试一试{
    const browser=wait puppeter.launch({
    无头:错,
    args:['--无沙盒']
    })
    console.log('浏览器已启动')
    const page=wait browser.newPage()
    console.log('页面已打开')
    wait page.goto(url,{waitUntil:'domcontentloaded'})
    wait page.waitForSelector('正文')
    console.log('链接已打开')
    const body=wait page.evaluate(el=>el.innerHTML,wait page.$('body'))
    控制台日志(正文)
    browser.close()
    返回体
    }捕捉(错误){
    console.log(错误)
    }
    }
    
    对于脚本的一部分,您的等待超时有点过于复杂。我建议作出以下更改:

  • 如果您不确定是什么原因导致超时,则应设置
    headless:false
    ,以便您可以在UI上查看出了什么问题,您可以打开浏览器控制台等
  • 在脚本使用
    waitForSelector
    -s执行您想要的操作之前,不要设置超时。我从你的脚本中删除了它们
  • 如果您对每个网络事件都不感兴趣(尤其是对分析和跟踪请求不感兴趣),但只需要DOM,那么请使用
    waitUntil:'domcontentloaded'
    ,而不是
    load
    或最严格的
    networkidle2
    !在文档中查看它们之间的确切区别:
  • 在等待选择器后,不要等待导航。这就是脚本失败的主要原因:一旦
    出现在DOM中,您要求木偶演员等待导航完成,但此时您没有导航:您已经在页面上了。请记住:
    page.waitForNavigation
    在页面导航到新URL或重新加载时解析。当您运行代码时,它非常有用,因为代码会间接导致页面导航

  • 您的
    页面.eval$
    缺少异步特性,但它应该始终是异步的。无论如何,
    innerHTML
    可以通过:
    wait page.evaluate(el=>el.innerHTML,wait page.$('body'))更简单地检索
  • const scrape=async url=>{
    试一试{
    const browser=wait puppeter.launch({
    无头:错,
    args:['--无沙盒']
    })
    console.log('浏览器已启动')
    const page=wait browser.newPage()
    console.log('页面已打开')
    wait page.goto(url,{waitUntil:'domcontentloaded'})
    wait page.waitForSelector('正文')
    console.log('链接已打开')
    const body=wait page.evaluate(el=>el.innerHTML,wait page.$('body'))
    控制台日志(正文)
    browser.close()
    返回体
    }捕捉(错误){
    console.log(错误)
    }
    }
    
    感谢您的解释和解决方案。我在Heroku上运行了代码,它运行得很好,但是我在本地机器上的Chromium中出现了256个错误。但我认为这个问题已经解决了,我必须找到解决256错误的方法。再次感谢你!我明白了,我想如果它在Heroku上运行,那么您已经添加了所需的构建包:。错误256与GPU有关,如果您已修复代码
    headless:true
    ,则可以再次启用(它不会