如何使用 Puppeteer 或 Chrome 控制台以编程方式切换 JS 上下文(到不同域的 iframe 上下文)

Sta*_*sky 5 javascript iframe google-chrome google-chrome-devtools puppeteer

我想使用 Puppeteer 从放置在页面 iframe 内的选择器获取数据,该页面在与其父框架域不同的域上运行。我不是任何域的所有者,因此 - 不能使用frame.postMessage。

尝试引用选择器

document.querySelector('#selector_inside_iframe')
Run Code Online (Sandbox Code Playgroud)

但由于 iframe 内的选择器 - 它在主上下文中是不可见的。当尝试使用时

document.querySelector('#selector_inside_iframe').contentWindow.document
Run Code Online (Sandbox Code Playgroud)

因为 iframe 使用不同的域 - 它被 CORS 阻止。当在 Chrome 控制台选项卡上的 JS 上下文下拉列表中手动更改 JS 上下文时,它可以工作,但是,需要使用 Puppeteer 来完成。

JS 上下文下拉

我希望获得对节点“#selector_inside_iframe”的引用,但如果不更改 Chrome 开发工具内的上下文,则会出现以下错误:

'Uncaught DOMException: Blocked a frame with origin "https://blah.some_domain.com" from accessing a cross-origin frame'
Run Code Online (Sandbox Code Playgroud)

Sta*_*sky 7

我能够通过使用 Puppeter 解决这个问题ElementHandle.contentFrame()

iframe首先使用选择器作为ElementHandle对象引用

const iframeHandle = await page.$('iframe')

然后像这样引用iframe上下文ElementHandle.contentFrame()

const contentFrame = await iframeHandle.contentFrame()

现在要查询 iframe 内的 html/css 选择器,只需使用contentFrame 如下所示:

contentFrame.$('.data_class')