Puppeteer - 为拦截的请求设置导航超时

Puppeteer - set navigation timeout for intercepted request

脚本执行导航到给定的 HTML 字符串,表示网页。有一个函数可以处理拦截的请求和 abort 那些类型不允许的请求。对于请求 continue 的所有其他请求,我想设置特定的超时,不同于页面加载超时(脚本未设置它,但默认 goto 超时为 30 秒)。例如,如果资源类型是 'image' 我想等待不超过 5 秒,然后中止请求。以下是脚本片段...

await page.setRequestInterception(true);
let firstDocument = true;
page.on('request', interceptedRequest => {
    const resType = interceptedRequest.resourceType();
    if ((resType === "document" && firstDocument) || settings.getAllowedResourceTypes().indexOf(resType) !== -1) {
        if (resType === "document") {
            firstDocument = false;
        }
        interceptedRequest.continue();
    } else {
        interceptedRequest.abort();
    }
});
await page.goto(`data:text/html;charset=UTF-8,${html}`, { waitUntil: 'networkidle0' }).catch((e) => { logger.warn(e, "Unable to load HTML page content."); });
// ... move on with HTML processing

是否可以只为特定拦截的请求设置超时?

According to the puppeteer developers协议目前不支持。

但是有一个 "hacky" 方法可以做到这一点(如 here 所述):您可以在拦截请求并自己应用超时后自行下载资源。请记住,您可能需要自己处理 cookie 和其他 HTTP headers:

page.on('request', interceptedRequest => {
    const resType = async interceptedRequest.resourceType();
    if (resType === 'image') {
        // download the image yourself
        const body = await Promise.race([
            fetchResourceYourself(interceptedRequest.url()), // might need to take care of cookies, headers, ...
            new Promise(resolve => setTimeout(resolve, 5 * 1000)) // your timeout
        ]);
        if (body) {
            interceptedRequest.respond({ body });
        } else {
            interceptedRequest.abort();
        }
    } else {
        interceptedRequest.continue();
    }
});