8

Since ESPN does not provide an API, I am trying to use Puppeteer to scrape data about my fantasy football league. However, I am having a hard time trying to login using puppeteer due to the login form being nested with an iframe element.

I have gone to http://www.espn.com/login and selected the iframe. I can't seem to select any of the elements within the iframe except for the main section by doing

    frame.$('.main')

This is the code that seems to get the iframe with the login form.

    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()

I want to be able to access the username field, password field, and the login button within the iframe element. Whenever I try to access these fields, I get a return of null.

hardkoded
  • 13,167
  • 3
  • 34
  • 48
SwapnikK
  • 83
  • 1
  • 1
  • 3

3 Answers3

22

You can get the iframe using contentFrame as you are doing now, and then call $.

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 frame.waitForSelector('[ng-model="vm.username"]');
const username = await frame.$('[ng-model="vm.username"]');
await username.type('foo');
await browser.close()

enter image description here

hardkoded
  • 13,167
  • 3
  • 34
  • 48
8

I had an issue with finding stripe elements. The reason for that is the following:

You can't access an with different origin using JavaScript, it would be a huge security flaw if you could do it. For the same-origin policy browsers block scripts trying to access a frame with a different origin. See more detailed answer here

Therefore when I tried to use puppeteer's methods:Page.frames() and Page.mainFrame(). ElementHandle.contentFrame() I did not return any iframe to me. The problem is that it was happening silently and I couldn't figure out why it couldn't find anything.

Adding these arguments to launch options solved the issue: '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process'

michaelklim.pro
  • 467
  • 5
  • 9
-1

await elementHandle.contentFrame() is null:

const frame = await elementHandle.contentFrame(); 
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120