【问题标题】:Image shows 1 thing, but queried data shows another when loading a website图片显示一件事,但在加载网站时查询的数据显示另一件事
【发布时间】:2020-03-21 03:28:29
【问题描述】:

我试图查询一个网站:const url = "https://personal.vanguard.com/us/FixedIncomeHome",希望能自动化 puppeteer 中的某些功能。

我注意到如果我创建一个屏幕截图:page.screenshot("preclick.png") 它会显示带有标签的页面数据。当我尝试通过查询跟进它时,它似乎没有返回第二个选项卡(由以下选择器表示:a[container="CD"]

const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(url, {waitUntil: 'networkidle2'})
page.screenshot("start.png")
page.evaluate( () => {
    document.querySelectorAll("a[container='CD']")[0].click()
})
///...

我真的不知道为什么会这样。理想情况下,我尝试单击 CD,然后单击空搜索。我注意到,由于会话 ID 被跟踪,我想将其作为一种 E2E 测试来执行,以获取结果表数据。

我看到选项卡等的内容是动态加载的,所以不知何故页面无法查询。

我正在尝试其他方法来查看会发生什么,等待标签出现,但它会在 30 秒后超时:

await page.waitForSelector("a[container='CD']").then( async resolve => {
     page.execute( () => document.querySelector("a[container='CD']").click() );
});

我不知道为什么屏幕截图显示了 HTML,但是当尝试从执行中查询它时它失败了。为什么会发生这种情况对我来说没有意义。理想情况下,我想点击 CD 选项卡,然后我想点击搜索,然后我想遍历表中的 20 个结果。

EDIT 我注意到由于 iframe,evaluate 没有正确查询组件。但是,如果我想开发 e2e 测试,我认为有一种方法可以以某种方式获取对按钮的引用并单击它,或者模拟单击。*

【问题讨论】:

  • 即使让它工作起来可能有点棘手,我建议您在用户会话下调试(而不是在无头模式下)。我解决了类似的问题,您需要找出那里发生的事情(控制台等)。 networkidle2 也意味着“至少 500 毫秒内不超过 2 个网络连接”,这是不安全的。我使用 networkidle0 来确保根本没有连接。
  • 我不是在无头的情况下运行它,以查看评估是如何工作的。我注意到文档是正确的,但是在我检查页面之前,查询选择器没有返回信息。文档中引用的内容和代码中的内容似乎存在差异
  • 我希望有一种方法可以进行某种“更新”来重新量化文档对象。
  • 看起来确实有一个 Iframe 正在禁止文档查询命令,但我想用 puppeteer 我可以像 XML 或其他东西一样查询它以便处理。似乎埋入嵌套的 iframe 可能会导致诸如 Cross Origin 之类的问题。即使这是 Cross Origin,我也会认为我可以使用 Puppet 进行 E2E 测试以执行点击
  • 注意我没有在页面上执行 js,所以现在我正在查看 API 文档并且没有 page.execute。我只能找到page.evaluate 方法。你是在哪里拿到的? document.querySelector("a[container='CD']").click() 在您的控制台中工作对吗?至少应该有一些错误,如果没有,你应该记录每一步。

标签: javascript html node.js puppeteer


【解决方案1】:

您可以从选择器中获取iframe。由于iframe 的ID 为TWRIFrame,您可以等待该选择器,然后从该元素中获取contentFrame
一旦你有了框架,frame class 就具有与页面类几乎相同的功能,例如click.

请注意,由于 iframe 来自其他域,带有 --disable-features=site-per-process 标志。

const browser = await puppeteer.launch({headless: false, args: ['--disable-features=site-per-process']});
const page = await browser.newPage();
await page.goto('https://personal.vanguard.com/us/FixedIncomeHome', {waitUntil: 'networkidle2'});
await page.screenshot("start.png");
await page.waitForSelector('#TWRIFrame');
const frameElement = await page.$('#TWRIFrame');
const frame = await frameElement.contentFrame();
await frame.click("a[container='CD']");

【讨论】:

  • 这对你有用吗?似乎我得到了 UnhandledPromiseRejectionWarning: No node found for selector: a[container='CD']
  • 它确实对我有用。也许之前添加一个waitForSelector?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
相关资源
最近更新 更多