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



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

可以使用Nodejs和Puppeteer 获取HTTP响应标头

然而,我有一个特殊的情况,初始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秒。

您可以使用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', '--disable-setuid-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?://([^?/]+)(/|)([^nr?.]+|) *$/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();

最新更新