How do I make Puppeteer only click selector with a set "status"?

Viewed 29

I am trying to make a bot to help me buy tickets but, as the picture shows, only a few seats are available.

I have a problem to work out how to make Puppeteer only click the available seats.

In the picture below, there are a lot of sold seats and some available ones. In the developer tools to the right side in the picture I can easily separate the sold seats from the available ones by looking at the data-status="available" part.

I have managed to make the bot click every seat, but not to only click the green ones. If possible, I also only want it to click a couple of green ones, and not all of them, 3 to 4 would be perfect.

Image of available seats: due to low reputation I have to link the image

The code I have for clicking the seats looks like this (and keeps going until it has clicked all the seats):

    await page.waitForSelector("#arena > div > div > div > div > div > div > div:nth-child(1)"
    await page.click ("#arena > div > div > div > div > div > div > div:nth-child(1)"), elem => elem.click();
    await delay(10);
    await page.click ("#arena > div > div > div > div > div > div > div:nth-child(2)"), elem => elem.click();
    await delay(10);
    await page.click ("#arena > div > div > div > div > div > div > div:nth-child(3)"), elem => elem.click();
    await delay(10);
    await page.click ("#arena > div > div > div > div > div > div > div:nth-child(4)"), elem => elem.click();
    await delay(10);
    await page.click ("#arena > div > div > div > div > div > div > div:nth-child(5)"), elem => elem.click();

I want it to click the seats with the value data-status="available"

I added await delay because there is a pop up that fades in when you have to "confirm seat" which I will be implementing later, as I feel that should be fairly easy.

How do I make Puppeteer only click available seats?

1 Answers

Try selecting those seats by the data attribute:

await page.$$eval(
  '.tc-section--seat[data-status="available"]',
  els => els.forEach(e => e.click())
);

Maybe use #arena .tc-section--seat[data-status="available"] if there are other sections that you need to disambiguate.

Alternately, if you want to use trusted Puppeteer clicks:

const seatEls = await page.$$('.tc-section--seat[data-status="available"]');

for (const el of seatEls) {
  await el.click();
}

I suggest steering clear of those browser generated selectors. They're simultaneously too specific and vague at the same time (not using a clear-cut class or data attribute, instead using a giant rigidly-specified tree of plain tag names).

Related