4

So I want to click on a button on a website. The button has no id, class,... So I should find a way to click the button with the name that's on it. In this example I should click by the name "Supreme®/The North Face® Leather Shoulder Bag"

This is my code in Node.js

const puppeteer = require('puppeteer');

let scrape = async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://www.supremenewyork.com/shop/all/bags');
await page.click(...);
browser.close();
return result;
};

This is the element that I want to click:

<a class="name-link" href="/shop/bags/a9cz4te2r/rsth86fbl">Supreme®/The 
North Face® Leather Shoulder Bag</a>
wizencrowd
  • 43
  • 1
  • 2
  • 7
  • Could not find any such `name-link` class or this name `Supreme®/The North Face® Leather Shoulder Bag` in the landing page. Where did you get this? – SIM Oct 20 '18 at 11:30
  • I got it from this link: https://www.supremenewyork.com/shop/all/bags. And Then the first bag on the second row, it under the
    tag then under

    – wizencrowd Oct 20 '18 at 11:38
  • Is this the url `https://www.supremenewyork.com/shop/bags/dd3wmsh9x/a05ivugj2` connected to that bag? If it is, you picked the wrong elements. – SIM Oct 20 '18 at 11:42
  • That link doesn't work for me. I guess it is because you are from an other part of the world. – wizencrowd Oct 20 '18 at 12:03
  • I've provided a selector below based on your elements above. Just use that within the script. – SIM Oct 20 '18 at 12:04

3 Answers3

7

Here is a way to collect that data. Try these on your browsers console first.

[...document.querySelectorAll('a.name-link')]
.filter(element => 
  element.innerText.includes('Supreme®/The North Face® Leather Shoulder Bag')
)

What's going on here?

  • document.querySelectorAll finds all element with that selector.
  • .filter will return the result that matches the query.
  • .includes will return data that includes a given string.

If a.name-link does not work, then look for a, if that does not work, then find the parent item and use that.

Once you got the element on your browser, you can apply that on your code, click it etc.

Usage:

You can use page.evaluate to filter and click.

const query = "Supreme®/The North Face® Leather Shoulder Bag";

page.evaluate(query => {
  const elements = [...document.querySelectorAll('a.name-link')];

  // Either use .find or .filter, comment one of these
  // find element with find
  const targetElement = elements.find(e => e.innerText.includes(query));

  // OR, find element with filter
  // const targetElement = elements.filter(e => e.innerText.includes(query))[0];

  // make sure the element exists, and only then click it
  targetElement && targetElement.click();
}, query)
Md. Abu Taher
  • 17,395
  • 5
  • 49
  • 73
  • propably a silly question but i'm kind of new to this but what do these 3 points mean before document? – wizencrowd Oct 20 '18 at 14:21
  • That's a spread operator. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax – Md. Abu Taher Oct 20 '18 at 14:22
  • As I asked above, can you share a screenshot of the page you are trying to access? Otherwise share the source code of that page somewhere. Otherwise it's all just guessing what works etc. – Md. Abu Taher Oct 20 '18 at 14:26
  • I removed that accepted thing by accident, because your code works. . Btw this is the link https://www.supremenewyork.com/shop/all/bags – wizencrowd Oct 20 '18 at 14:31
  • No, I am not talking about the link, it's about the screenshot. It doesn't show here like you are seeing. I tried with proxies too. Just doesn't show any name anywhere. – Md. Abu Taher Oct 20 '18 at 14:33
  • I just guessed what you were trying to do and provided a solution based on that. – Md. Abu Taher Oct 20 '18 at 14:33
  • This is what I see: http://prntscr.com/l8bhwh This is the element that I need to click on : http://prntscr.com/l8bioh But as you can see there are also multiple colors: http://prntscr.com/l8bivx I need to select the right colour too. Thanks – wizencrowd Oct 20 '18 at 14:38
  • Ah so Supreme shows that data for london. Great. The above snippet should work perfectly. :) – Md. Abu Taher Oct 20 '18 at 14:41
0

If I got you right, the following piece of code should let you click on that link:

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://www.supremenewyork.com/shop/all/bags');
await page.click("a[href$='a05ivugj2']");
await browser.close();
})();
SIM
  • 21,997
  • 5
  • 37
  • 109
  • Btw, If the elements available from your end are in reality what you have pasted above then replace this portion `page.click("a[href$='a05ivugj2']")` with `page.click("a[href$='rsth86fbl']")` from within my script above. – SIM Oct 20 '18 at 12:02
  • If I change the href$ to ckf2cimj7 it will work for me. I guess this is because the website works regional. But the problem is I wont be able to get that tag before the item goes online. The only thing I will know before it goes online is the name of the item. So I need to find a way to click the link by the name "Supreme®/The North Face® Leather Shoulder Bag". – wizencrowd Oct 20 '18 at 12:08
  • The name you mentioned is not available in that page (at least from my end) when I search it through chrome dev tools. – SIM Oct 20 '18 at 12:35
  • It is the name of the item itself. http://prntscr.com/l8ahbr and http://prntscr.com/l8ahwc – wizencrowd Oct 20 '18 at 12:39
  • This is how I can see [check out this link](https://www.dropbox.com/s/q4zvpt09pus04na/Untitled.jpg?dl=0). – SIM Oct 20 '18 at 12:42
  • ok, that's weird. But do you got any idea how I can click the link only using the name of the item with the screenshots I gave you? – wizencrowd Oct 20 '18 at 12:54
  • As `.querySelector()` doesn't support pseudo-selectors, you need to avail `xpath` to click on that link defining ***`.='Supreme®/The North Face® Leather Shoulder Bag'`*** within it. – SIM Oct 20 '18 at 12:59
0

The following function will click the first element that matches certain text:

const clickText = text => {
    return page.evaluate(text => [...document.querySelectorAll('*')].find(e => e.textContent.trim() === text).click(), text);
};

You can use the function in your Puppeteer script using the following method:

await clickText('Supreme®/The North Face® Leather Shoulder Bag');
Grant Miller
  • 27,532
  • 16
  • 147
  • 165