Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 木偶演员:如何只等待第一反应(HTML)_Node.js_Puppeteer_Puppeteer Cluster - Fatal编程技术网

Node.js 木偶演员:如何只等待第一反应(HTML)

Node.js 木偶演员:如何只等待第一反应(HTML),node.js,puppeteer,puppeteer-cluster,Node.js,Puppeteer,Puppeteer Cluster,我正在使用Puppeter群集来抓取网页 如果我在每个网站上一次打开多个页面(8-10页),连接速度会减慢,并且会出现许多超时错误,如下所示: 超时错误:超过导航超时:超过30000ms 我只需要访问每个页面的HTML代码。我不需要等待domcontentloaded等等 有没有办法告诉page.goto()只等待来自Web服务器的第一个响应?或者我需要使用另一种技术而不是Puppeter?domcontentloaded是第一个html内容的事件 DOMContentLoaded事件在初始HT

我正在使用Puppeter群集来抓取网页

如果我在每个网站上一次打开多个页面(8-10页),连接速度会减慢,并且会出现许多超时错误,如下所示:

超时错误:超过导航超时:超过30000ms

我只需要访问每个页面的HTML代码。我不需要等待domcontentloaded等等

有没有办法告诉page.goto()只等待来自Web服务器的第一个响应?或者我需要使用另一种技术而不是Puppeter?

domcontentloaded是第一个html内容的事件

DOMContentLoaded事件在初始HTML文档完全加载和解析后激发,而不等待样式表、图像和子帧完成加载

以下内容将在加载初始HTML文档时完成加载

await page.goto(url, {waitUntil: 'domcontentloaded'})
但是,如果一次加载10个页面,您可以阻止图像或样式表以节省带宽并更快地加载

将下面的代码放在正确的位置(在使用
page.goto
导航之前),它将停止加载图像、样式表、字体和脚本

await page.setRequestInterception(true);
page.on('request', (request) => {
    if (['image', 'stylesheet', 'font', 'script'].indexOf(request.resourceType()) !== -1) {
        request.abort();
    } else {
        request.continue();
    }
});
domcontentloaded是第一个html内容的事件

DOMContentLoaded事件在初始HTML文档完全加载和解析后激发,而不等待样式表、图像和子帧完成加载

以下内容将在加载初始HTML文档时完成加载

await page.goto(url, {waitUntil: 'domcontentloaded'})
但是,如果一次加载10个页面,您可以阻止图像或样式表以节省带宽并更快地加载

将下面的代码放在正确的位置(在使用
page.goto
导航之前),它将停止加载图像、样式表、字体和脚本

await page.setRequestInterception(true);
page.on('request', (request) => {
    if (['image', 'stylesheet', 'font', 'script'].indexOf(request.resourceType()) !== -1) {
        request.abort();
    } else {
        request.continue();
    }
});

@用户3817605,我为您提供了完美的代码。:)

/**
*方法`page.waitForNavigation`和`frame.waitForNavigation`等待页面
*事件“domcontentloaded”的最小值。此函数返回解析为的承诺
*一旦指定的页面“事件”发生。
* 
*@param{puppeter.Page}Page
*@param{string}event可以是“page.on()”方法接受的任何事件。例如:“requestfinished”或“framenavigated”。
*@param{number}[timeout]可选等待时间。如果未指定,将永远等待。
*/
函数waitForEvent(页面、事件、超时){
第页。一次(事件,完成);
让我们完成,timeoutId=(typeof timeout=='number'&&timeout>=0)?setTimeout(完成,超时):-1;
返回新承诺(resolve=>Complete=resolve);
函数完成(){
clearTimeout(timeoutId);
实现();
}
}
您要求函数只等待第一个响应,因此您可以这样使用此函数:

page.goto();//如果过早终止页面,请使用.catch(()=>{}),以避免在控制台上抛出错误
等待waitForEvent(第页“响应”);//在这一行之后,您已经收到了html响应
这正是你想要的。但请注意,“收到的响应”与“收到的完整html响应”不同。第一个是响应的开始,最后一个是响应的结束。因此,您可能希望使用事件“requestfinished”而不是“response”。事实上,您可以使用木偶玩家页面接受的任何事件。他们是: 关闭、控制台、对话框、domcontentloaded、错误、frameattached、FrameDistached、framenavigated、load、metrics、pageerror、popup、request、requestfailed、requestfinished、response、workercreated、workerdestroyed

尝试使用以下选项:requestfinished或framenavigated。也许它们会适合你

为了帮助您决定哪一个最适合您,您可以设置如下测试代码:

const puppeter=require('puppeter');
/**
*方法`page.waitForNavigation`和`frame.waitForNavigation`等待页面
*事件“domcontentloaded”的最小值。此函数返回解析为的承诺
*一旦指定的页面“事件”发生。
* 
*@param{puppeter.Page}Page
*@param{string}event可以是“page.on()”方法接受的任何事件。例如:“requestfinished”或“framenavigated”。
*@param{number}[timeout]可选等待时间。如果未指定,将永远等待。
*/
函数waitForEvent(页面、事件、超时){
第页。一次(事件,完成);
让我们完成,timeoutId=(typeof timeout=='number'&&timeout>=0)?setTimeout(完成,超时):-1;
返回新承诺(resolve=>Complete=resolve);
函数完成(){
clearTimeout(timeoutId);
实现();
}
}
(异步()=>{
const browser=wait puppeter.launch();
const page=wait browser.newPage();
const cdp=wait page.target().createCDPSession();
等待cdp.send('Network.enable');
等待cdp.send('Page.enable');
const t0=日期。现在();
page.on('request',req=>console.log(`>${Date.now()-t0}请求开始:${req.url()}`));
page.on('response',req=>console.log(`<${Date.now()-t0}响应:${req.url()}`);
page.on('requestfinished',req=>console.log(`.${Date.now()-t0}请求完成:${req.url()}`);
page.on('requestfailed',req=>console.log('E${Date.now()-t0}请求失败:${req.url()}`);
第页转到('https://www.google.com)。catch(()=>{});
等待waitForEvent(第页“requestfinished”);
log(`\n页面是在${Date.now()-t0}ms\n`)之后发布的;
等待页面。关闭();
等待浏览器关闭();
})();
/*输出应如下所示:
>2请求启动:https://www.google.com/
<355响应:https://www.google.com/
>387请求启动:https://www.google.com/tia/tia.png
>387请求启动:https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
. 389请求已完成:https://www.google.com/
该页面在389ms后发布
*/

@user3817605,我为您准备了完美的代码。:)

/**
*方法`page.waitForNavigation`和`frame.waitForNavigation`等待页面
*