【问题标题】:puppeteer being redirected when browser is not当浏览器没有被重定向时 puppeteer
【发布时间】: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。 这是我认为用户控制的浏览器会发生的事情:

  1. 页面请求已发送。 (假设第一次访问)

  2. 响应是纯JS,

  3. 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


【解决方案1】:

我没有完整的分辨率,但我知道重定向发生在哪里。

我在本地测试了您的脚本,如下所示:

const puppeteer = require('puppeteer');
const PuppeteerHar = require('puppeteer-har');

function run () {
    let url = 'https://publicindex.sccourts.org/anderson/publicindex/';
    puppeteer.launch({headless: false, devtools: true }).then(async browser => {
        const page = await browser.newPage();
        await page.setRequestInterception(true);
        page.on('request', request => {
            console.log('GOT NEW REQUEST', request.url());
            request.continue();
        });

        page.on('response', response => {
            console.log('GOT NEW RESPONSE', response.status(), response.headers());
        });
        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();
    });
};
run();

我编辑了三个部分:

  • 移除无头模式并自动打开开发工具
  • 拦截所有网络请求(我已审核)
  • 提升require 导入,因为它伤害了我的眼睛。我总是看到他们在没有嵌套的情况下打电话

转出页面https://publicindex.sccourts.org/anderson/publicindex/https://publicindex.sccourts.org/发出请求

但是这个请求返回一个 302 重定向到https://www.sccourts.org/caseSearch/ 位置,所以浏览器会相应地采取行动

我会尝试调查这个奇怪的请求是否合法以及为什么它会在 chrome puppeteer 上重定向

这个post 可能会有所帮助,这可能与铬被视为不安全有关

我也尝试将args: ['--disable-web-security', '--allow-running-insecure-content'] 传递给launch() 对象参数,但没有结果

请告诉我们进展如何!哈尔的发现很有趣!

【讨论】:

  • 感谢您的意见。手动测试时,不会向publicindex.sccourts.org 发出请求。似乎请求/重定向是在无头/有头模式下发生的,但是当我手动导航到目标 url 时没有发生。在尝试拦截每个请求以检查标头/cookie 时,我确实注意到我无法添加设置一些特定的标头 sec-fetch-dest: empty sec-fetch-mode: cors sec-fetch-site: same-origin
  • 是的,铬发生了一些奇怪的事情,我会联系 puppeteer。尝试打开一个新标签并手动输入地址,同样的事情总是发生。这是浏览器级别。我会尝试设置标志。你也可以试试火狐,npmjs.com/package/puppeteer-firefox
  • 我添加了一个具有更详细日志记录的版本......再次......感谢您的关注!
猜你喜欢
  • 2015-08-19
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
相关资源
最近更新 更多