如何在 Puppeteer 中选择 iframe 元素内的元素

21

由于ESPN不提供API,我正在尝试使用Puppeteer来爬取有关我的梦幻足球联赛的数据。然而,由于登录表单嵌套在一个iframe元素中,我很难使用puppeteer进行登录。

我已经进入http://www.espn.com/login并选择了iframe。但是除了通过以下方式选择主要部分外,似乎无法选择iframe内的任何元素

    frame.$('.main')

这是似乎可以获取登录表单iframe的代码。

    const browser = await puppeteer.launch({headless:false});
    const page = await browser.newPage();

    await page.goto('http://www.espn.com/login')
    await page.waitForSelector("iframe");

    const elementHandle = await page.$('div#disneyid-wrapper iframe');
    const frame = await elementHandle.contentFrame();
    await browser.close()

我希望能够访问iframe元素内的用户名字段、密码字段和登录按钮。每当我尝试访问这些字段时,都会返回null。

2个回答

62

你可以像现在这样使用contentFrame获取iframe,然后调用$

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

await page.goto('http://www.espn.com/login')

const elementHandle = await page.waitForSelector('div#disneyid-wrapper iframe');
const frame = await elementHandle.contentFrame();
await frame.waitForSelector('[ng-model="vm.username"]');
const username = await frame.$('[ng-model="vm.username"]');
await username.type('foo');
await browser.close()

输入图像描述


frame.$('[ng-model="vm.username"]') 似乎返回 null。 - SwapnikK
@SwapnikK 你也可以使用 waitForSelector。回答已编辑。 - hardkoded

14

我在查找Stripe元素时遇到了问题。原因如下:

使用JavaScript无法访问具有不同来源的<iframe>,如果可以这样做将是一个巨大的安全漏洞。出于同源策略,浏览器会阻止脚本尝试访问具有不同来源的框架。详细答案请看此处

所以当我尝试使用puppeteer的方法:Page.frames()Page.mainFrame().ElementHandle.contentFrame()时,它没有返回任何<iframe>给我。问题在于发生了静默处理,我无法弄清楚为什么找不到任何东西。

将以下参数添加到启动选项即可解决问题: '--disable-web-security','--disable-features=IsolateOrigins,site-per-process'


1
非常感谢您的回答,这解决了我的问题。如果您知道的话,能否分享启用这些标志的任何缺点? - opensource-developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接