Click an element on first Google search result using Puppeteer

Viewed 937

Hello I'm just new to puppeteer and having a problem here by a week now and I just want to click on search result after searching the word 'Intel' on Google:

enter image description here

My source code:

const puppeteer = require('puppeteer');

async function search()  {
    const browser = await puppeteer.launch({executablePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome',
    headless: false});
    const page = await browser.newPage();
    await page.setViewport({ width: 1600, height: 1040 })
    await page.goto('https://google.com');
            await page.type('input.gLFyf.gsfi', 'Intel');
            page.keyboard.press('Enter');
            await page.waitForSelector('a');
   
            await navigationPromise
            var selectorString = '.yuRUbf > a > .LC20lb';
            var selector = await page.$(selectorString);
            if (selector!=null) {
                var element = selector.asElement();
                await element.click();
            }

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

I assume the problem is here

var selectorString = '.yuRUbf > a > .LC20lb';
1 Answers

This approach is on the right track but seems rather brittle. Prefer CSS selectors that are as generic as possible to help tolerate updates to the DOM structure.

In your code, navigationPromise is undefined; prefer page.waitForNavigation here to respond to the navigation triggered by the Enter key press.

await page.waitForSelector('a'); seems too weak to achieve much since most pages already have anchors all over them, so the predicate will be trivially true. Use a more precise selector.

Your approach to clicking can be simply page.click(selector) as shown below:

const puppeteer = require("puppeteer"); // ^16.2.0

let browser;
(async () => {
  const searchQuery = "intel";

  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto("https://www.google.com/", {waitUntil: "domcontentloaded"});
  await page.waitForSelector('input[aria-label="Search"]', {visible: true});
  await page.type('input[aria-label="Search"]', searchQuery);
  await Promise.all([
    page.waitForNavigation({waitUntil: "domcontentloaded"}),
    page.keyboard.press("Enter"),
  ]);
  await page.waitForSelector(".LC20lb", {visible: true});
  await Promise.all([
    page.waitForNavigation({waitUntil: "domcontentloaded"}),
    page.click(".LC20lb"),
  ]);
  console.log(await page.title()); // => Intel | Data Center Solutions, IoT, and PC Innovation
})()
  .catch(err => console.error(err))
  .finally(() => browser.close())
;

I'll add the standard note that disabling JS and blocking resources like images and stylesheets will substantially speed up the script. Scraping Google search result links with Puppeteer shows one approach to grab the data with a simple HTTP request and static HTML parser like cheerio.

Related