【发布时间】:2020-08-01 17:37:16
【问题描述】:
正在尝试测试页面https://publicindex.sccourts.org/anderson/publicindex/ 使用标准浏览器导航到页面时,导航会在请求的页面 (https://publicindex.sccourts.org/anderson/publicindex/) 处结束,页面显示“接受”按钮。
但是,在无头模式下使用 puppeteer 进行测试时,请求被重定向到 https://publicindex.sccourts.org。
我对正在发生的事情有一个粗略的了解,但似乎无法阻止在使用 puppeteer 请求页面时重定向到 https://publicindex.sccourts.org。 这是我认为用户控制的浏览器会发生的事情:
-
页面请求已发送。 (假设第一次访问)
-
响应是纯JS,
-
js代码指定为:
复制初始页面请求标头
添加特定的标题,并重新请求相同的页面(xhr)
从响应标头之一复制 url 并替换位置
(或)
检查页面历史记录,
将页面响应中的 url 添加到历史记录中,
打开一个新窗口,
将 xhr 响应写入新页面
关闭新窗口
为返回的 xhr 请求中的函数添加事件监听器
触发事件
使用 puppeteer,我尝试过跟踪 js,记录 har,监控 cookie,查看请求链,拦截页面请求和调整 headers,查看历史......等等。我被难住了。
这是 puppeteer 脚本的最基本版本:
function run () {
let url = 'https://publicindex.sccourts.org/anderson/publicindex/';
const puppeteer = require('puppeteer');
const PuppeteerHar = require('puppeteer-har');
puppeteer.launch({headless: true}).then(async browser => {
const page = await browser.newPage();
await page.setJavaScriptEnabled(true);
await page.setViewport({width: 1920, height: 1280});
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
const har = new PuppeteerHar(page);
await har.start({path: 'results.har'});
const response = await page.goto(url);
await page.waitForNavigation();
await har.stop();
let bodyHTML = await page.content();
console.log(bodyHTML);
});
};
run();
当我在 chrome 中导航到页面并在“接受”页面上结束导航时,为什么我不能让 puppeteer 简单地复制 js 正在执行的过程?
这是一个具有更详细日志记录的版本:
function run () {
let url = 'https://publicindex.sccourts.org/anderson/publicindex/';
const puppeteer = require('puppeteer');
const PuppeteerHar = require('puppeteer-har');
puppeteer.launch().then(async browser => {
const page = await browser.newPage();
await page.setJavaScriptEnabled(true);
await page.setViewport({width:1920,height:1280});
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
await page.setRequestInterception(true);
page.on('frameattached', frame =>{ console.log('frame attached ');});
page.on('framedetached', frame =>{ console.log('frame detached ');});
page.on('framenavigated', frame =>{ console.log('frame navigated '); });
page.on('requestfailed', req =>{ console.log('request failed ');});
page.on('requestfinished', req =>{ console.log('frame finished '); console.log(req.url())});
let count = 0;
let headers = '';
page.on('request', interceptedRequest => {
console.log('requesting ' + count + 'times');
console.log('request for ' + interceptedRequest.url());
console.log(interceptedRequest);
if (count>2) {
interceptedRequest.abort();
return;
}
if (interceptedRequest.url() == url) {
count++;
if (count == 1) {
const headers = interceptedRequest.headers();
headers['authority'] = 'publicindex.sccourts.org';
headers['sec-fetch-dest'] = 'empty';
headers['sec-fetch-mode'] = 'cors';
headers['sec-fetch-site'] = 'same-origin';
headers['upgrade-insecure-requests'] = '1';
interceptedRequest.continue({headers});
return;
} else {
interceptedRequest.continue();
return;
}
}
count++;
interceptedRequest.continue();
return;
});
const har = new PuppeteerHar(page);
await har.start({ path: 'results.har' });
await page.tracing.start({path: 'trace.json'});
await Promise.all([page.coverage.startJSCoverage({reportAnonymousScripts : true})]);
const response = await page.goto(url);
const session = await page.target().createCDPSession();
await session.send('Page.enable');
await session.send('Page.setWebLifecycleState', {state: 'active'});
const jsCoverage = await Promise.all([page.coverage.stopJSCoverage()]);
console.log(jsCoverage);
const chain = response.request().redirectChain();
console.log(chain + "\n\n");
await page.waitForNavigation();
await har.stop();
let bodyHTML = await page.content();
console.log(bodyHTML);
});
};
run();
【问题讨论】:
-
您能否详细说明预期结果和当前行为? “导航以显示“接受”按钮的页面结束”是什么意思?您是否尝试过在没有无头模式的情况下运行以直观地检查发生了什么?
-
我编辑了帖子以使其更加清晰。关于在没有无头模式的情况下进行测试以观察视觉变化,在 chrome 中手动导航到 url 时似乎不会发生视觉变化。整个过程在对页面的初始导航请求之后立即发生。因此没有时间进行任何鼠标移动检测或其他用户输入检测。但我会尝试非无头模式。
-
我设法在本地复制。确实很奇怪,哈哈
-
我发现了问题,写了
标签: javascript node.js puppeteer