Кукольник как указать кнопку, если существует несколько кнопок одного и того же типа класса?

#javascript #html #puppeteer

Вопрос:

Я пытаюсь использовать Кукольника, чтобы нажать на кнопку.

Веб-страница в моем скрипте имеет сетку, которая действует как календарь, и каждая дата представляет собой кнопку. Проблема в том, что каждая кнопка даты относится к одному и тому же типу класса, и я поэтому не смог выделить конкретную дату.

Я попытался идентифицировать кнопки по ярлыку aria, но это все равно не сработало.

Затем я попытался нажать кнопку «Перейти на 5 дней вперед», используя метку aria, и это тоже не сработало.

Я читал, что это может быть доступно, выполнив итерацию по родительскому элементу в дереве HTML, а затем просто выбрав тот, который я хочу (пример: поместите элемент календаря в переменную, а затем выберите нужного мне ребенка[7]), но это действительно не идеально, и я надеюсь, что есть другой способ.

 const puppeteer = require ('puppeteer');

async function Main()
{
    const browser = await puppeteer.launch({product: 'chrome', headless: false});
    const page1 = await browser.newPage();
    const url1 = 'https://www.recreation.gov/camping/campgrounds/232446/availability';
    await page1.goto(url1);
    return page1;
}

async function selectDates(page){
    const button = await page.$('aria/Go Forward 5 Days[role="button"]');
    await button.click();
}

async function startCheckout()
{
    const page = await Main();
    await selectDates(page);
}

startCheckout();
 

Вот кнопка в HTML, если это поможет:

 <button class="rec-availability-date" aria-label="Jun 10, 2021 - Not Available">X</button>
 

Комментарии:

1. Добро пожаловать в SO! Я сократил ваш текст-после всего прочитанного я все еще не уверен, на какую кнопку вы хотите нажать. Можете ли вы уточнить, что делает кнопку, которую вы показали, особенной? Это 7 — я кнопка, метка арии,….? Спасибо.

2. @ggorlen привет, спасибо за это. да, я думаю, что моя стена текста была немного длинной, ха-ха. Реально кнопка, на которую я хотел бы нажать больше всего, — это любая из доступных кнопок даты. Если вы зайдете на веб-страницу, вы увидите, что большинство из них зарезервированы, поэтому они не доступны для просмотра, но те, которые доступны, доступны. Я могу зайти на сайт like bestbuys и нажать на что угодно, но на этой странице я не могу заставить его работать.

3. Итак, вы хотите проверить все доступные ячейки «А» или только определенные? Вы хотите добавить в корзину позже или…? Доступные кнопки, похоже, находятся в td.available элементах, поэтому я бы попробовал button.click("td.available .rec-availability-date"); , хотя еще не тестировал это.

4. @ggorlen Только конкретные даты. Допустим, например, 26 — е число этого месяца было доступно. Я хотел бы указать в коде, что я хочу нажать на 26-е для ячеек A. Затем я бы автоматически нажал «добавить в корзину», только если бы дата была доступна, и мой скрипт щелкнул по ней. Спасибо, я попробую то, что вы предложили, по крайней мере, чтобы посмотреть, смогу ли я управлять щелчком мыши. Если у вас есть идея, как я мог бы нажать на конкретную дату, хотя я бы с удовольствием ее послушал.

Ответ №1:

Правильный синтаксис для выбора элементов DOM с помощью их атрибутов таков:

 // Click "5 days > "
await page.click('[aria-label="Go Forward 5 Days"]');

// Click a specific day:
await page.click('[aria-label="Jun 17, 2021 - Site 091 is available"]');

// Add to cart
await page.WaitForSelector('button.availability-page-book-now-button-tracker');
await page.click('button.availability-page-book-now-button-tracker');
 

Также смотрите эти статьи о выборе элементов с помощью атрибутов:

Комментарии:

1. Здравствуйте, спасибо вам за вашу помощь. Я попробовал ваше предложение, но, к сожалению, оно не сработало. Я получаю это сообщение об ошибке: Ошибка: Не найден узел для селектора: [aria-метка=»Перейти на 5 дней вперед»]. Это сбивает с толку, потому что это метка aria на этой кнопке, и, насколько я понимаю, кнопка-это узел в дереве DOM. ПРАВКА: Я думаю, что это сработало только один раз. Но только один раз и после повторного запуска сценария, ничего не меняя, он продолжает терпеть неудачу. Я знаю, что это тоже сработало, потому что в терминале нет ошибки. Возможно ли, что он пытается нажать кнопку до того, как она загрузится?

2. Итак, глядя на документы кукольника, кажется, что у page.goto есть опция waituntil. Ну, я добавил опцию ожидания загрузки содержимого: ожидание страницы 1.goto(url2, {waitUntil: ‘domcontentloaded’ }); и теперь она работает большую часть времени. Я все еще время от времени получаю ту же ошибку «узел не найден», и я также заметил, что если я прокручу страницу колесом прокрутки мыши, она выдаст ошибку, в которой говорится, что узел не виден или не является элементом html. В общем, мы делаем успехи, ха-ха. Если у вас есть какие-либо идеи о том, что вызывает редкое сообщение об ошибке сейчас, я бы хотел его услышать, потому что я заблудился

3. Обязательно waitForSelector для узлов, с которыми вы хотите взаимодействовать (если они будут присутствовать на 100%)

4. Здравствуйте, Вавилофф, последний вопрос, почему вы использовали: страницу ожидания. waitForSelector(«кнопка.доступность-страница-книга-сейчас-кнопка-трекер»); если это только часть имени класса. Будет ли puppeter искать строку, соответствующую тому, что вы ввели, и назначать ее для waitForSelector и методов щелчка?

5. Этого селектора, хотя и частичного, достаточно, чтобы точно соответствовать только одной конкретной кнопке, которую мы ищем.