使用Node.js和Puppeteer定时重定向后的HTTP响应标头

下面已经回答了如何使用Puppeteer获取响应头:

Possible to get HTTP response headers with Nodejs and Puppeteer

但是,在一种特殊情况下,初始URL会在几秒钟后重定向到另一个URL。

这是我正在运行的相关代码:

const browser = await puppeteer.launch({args: ['--no-sandbox','--disable-setuid-sandbox'],headless: false});

const page = await browser.newPage();

// get the response object of the initial URL
var page_response_obj = await page.goto(url_str,{timeout: PAGE_TIMEOUT_GOTO_MS,waitUntil: 'domcontentloaded'});

// get page title of initial page
var page_title_1_str = await page.title();

// wait for a few seconds to cover the timed redirect
await page.waitFor(6130);

// get page title of final page
var page_title_2_str = await page.title();

我可以获取两个不同页面的页面标题,但是由于page_response_obj将包含初始URL的响应头,因此我不确定如何获取响应头。

是否可以获取最终URL的响应标头?

编辑

我正在将其用于具有Cloudflare保护的网站,在该网站上您需要等待大约5秒钟才能重定向到实际网站。

caoqiuli 回答:使用Node.js和Puppeteer定时重定向后的HTTP响应标头

您可以使用Request对象的链接重定向属性。

const puppeteer = require ('puppeteer')
const url = 'http://doodle.google.com/'

;(async () => {
    const browser = await puppeteer.launch({
        args: ['--no-sandbox','--disable-setuid-sandbox'],headless: true
    })

    const page = (await browser.pages())[0]

    // get the response object of the initial URL
    const response = await page.goto(url,{timeout: 0,waitUntil: 'domcontentloaded'})

    // get the first response header
    console.log ( response.headers() )

    // get page title of initial page
    const title1 = await page.title()

    const chain = response.request().redirectChain()

    // If the page redirected,all of chained response headers will be shown here
    for ( let num in chain ) {
        console.log( chain[num].response().headers() )
        // console.log(chain[0].url()) // => print the URL
    }

    // get page title of final page
    const title2 = await page.title()
})()
,

仔细检查后发现,某些重定向可能会(通过脚本)在前端强制执行,因此可能无法在标准重定向链中捕获。因此,我对Edi的建议没有成功。

因此,这是我需要进行更改以使事情正常工作的原因:

  1. 使用响应事件处理程序
  2. 等待很长时间(30到45秒),以确保您在重定向后捕获了相关的响应。您可以根据需要调整时间长度。

就我而言,我试图确定是否启用了gzip,因此我需要在最终URL上使用有效的响应对象。这是修改后的代码:

// define url and host
var url_str = 'https://www.example.com';
var url_host_str = 'example.com';

// define GZIP test function
var _checkGZIP = function(resp_headers_obj)
{
    var resp_header_content_encoding_str = resp_headers_obj['content-encoding'];
    var is_gzip_bool = !!(/gzip/i.test(resp_header_content_encoding_str));

    return is_gzip_bool;
};

const browser = await puppeteer.launch({args: ['--no-sandbox',headless: true});

const page = await browser.newPage();

// set result variable outside event handler scope
var is_gzip_bool = false;

/**
 * Set response event handler
 * This will capture all responses from the initial URL and from final URL
 */
page.on('response',function(response_obj)
{    
    // get URL and headers
    var resp_url_str = response.url();
    var resp_headers_obj = response.headers();

    if(!is_gzip_bool)
    {
        // check for only specific URLs
        if(/^ *https?\:\/\/([^\?\/]+)(\/|)([^\n\r\?\.]+|) *$/i.test(resp_url_str) && resp_url_str.includes(url_host_str))
        {
            // do gzip test
            is_gzip_bool = _checkGZIP(resp_headers_obj);
        }
    }
}

// go to page
await page.goto(url_str,{timeout: PAGE_TIMEOUT_GOTO_MS,waitUntil: 'domcontentloaded'});

// wait for a long while to capture all relevant responses [from both initial and final URL]
await page.waitFor(30000);

// document your result if required

// close browser
await browser.close();
本文链接:https://www.f2er.com/3164342.html

大家都在问