21

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
  • 18,915
  • 3
  • 52
  • 64
SwapnikK
  • 213
  • 1
  • 2
  • 4

2 Answers2

60

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

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

enter image description here

lezhumain
  • 387
  • 2
  • 8
hardkoded
  • 18,915
  • 3
  • 52
  • 64
14

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'

mykhailoklym94
  • 577
  • 6
  • 13