Waiting for Google Captcha to be displayed using puppeteer

Viewed 1575

I can't verify if a div exists or not on the page using Puppeteer, and I don't know why... I would like to scope the captcha on the page using this code:

puppeteer
    .launch(options)
    .then(async (browser) => {
      const page = await browser.newPage();
      await page.setViewport({ width: 1280, height: 720 });
      console.log("[+] Connecting...");
      await page.goto("https://www.google.com/recaptcha/api2/demo");
      console.log("[+] Connected");
      page.waitForNavigation()
      if (await page.$('div.recaptcha-checkbox-border') !== null)
        console.log('[+] Resolving captcha');
  })
  .catch((err) => {
    console.log(err);
  });

But my if is alaways false and I don't know why.

Here is a screenshot of the element scoped manually:

scoped element

1 Answers

This script should work

'use strict';

const puppeteer = require('puppeteer');

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

  console.log("Opening page");
  await page.goto('https://www.google.com/recaptcha/api2/demo');
  console.log("Opened page");

  const frame = await page.frames().find(f => f.name().startsWith("a-"));
  await frame.waitForSelector('div.recaptcha-checkbox-border');
  console.log("Captcha exists!");

  await browser.close();
})();

It appears that the captcha is inside an iframe that always starts with name=a- (however I can't confirm that with my limited testing)

You first need to get the iframe then await for the selector after the iframe has loaded. This is the output, try changing the iframe name or the selector name to see it fail.

output

Related