Не могу нажать кнопку cookie с помощью кукловода

Я пытаюсь закрыть баннер/модальный файл cookie на сайте, и мне кажется, что нажатие кнопки и элементов тега с кукловодом у меня не работает. Баннер/модальное окно cookie всегда остается на снимке экрана, который я делаю. Кроме того, когда я регистрирую кнопку или использую условие if, она ее находит. Кажется, проблема с самим щелчком, а не с поиском элемента. Я попробовал несколько методов. Я пытаюсь отладить это уже несколько дней и не могу понять.

Это мой код. сайт make.uk — это всего лишь пример. Мои сайты написаны на чешском языке, поэтому я не хотел вводить людей в заблуждение.

const puppeteer = require("puppeteer");

(async function main() {
  try {
    const browser = await puppeteer.launch({
      headless: true,
      defaultViewport: {
        width: 1920,
        height: 1080,
      },
    });
    const page = await browser.newPage();

    const response = await page.goto("https://makeup.uk/", {
      waitUntil: ["domcontentloaded", "networkidle2"],
    });

    // first way, doesn't work
    const xp = '::-p-xpath("//button[contains(text(), "Accept")]")';
    const el = await page.waitForSelector(xp);
    await el.click();

    // second way, doesn't work
    const buttons = await page.$$('::-p-xpath("//button")');
    for (const button of buttons) {
      let text = await button.evaluate((el) => el.textContent);
      if (text.includes("Accept")) {
        console.info("Found my button!"); //This logs in the console!
        await button.evaluate((b) => b.click());
      }
    }

const date = new Date().toTimeString();
    await page.screenshot({ path: date + ".png", fullPage: true });
    await browser.close();
  }

    catch (err) {
      console.error(err);
    }
  })();

Если я ввожу el первым способом в терминале, он говорит:

el CdpElementHandle {
  handle: CdpJSHandle {},
  [Symbol(_isElementHandle)]: true
}

что я понимаю как - я нашел элемент.

Я попробовал несколько других способов, например найти его в page.evaluate(), и даже не помню, что еще, результат тот же. Каждый раз, когда я нахожу кнопку, простое нажатие ничего не дает. Баннер cookie каждый раз находится на скриншоте. То же самое и с другими сайтами, не только с этим.

Моя версия кукольника такая (пробовал и самую последнюю) "puppeteer": "^22.4.1"

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У меня ваши селекторы работают нормально, хотя XPath не рекомендуется. '::-p-xpath("//button")' может быть просто 'button' как селектор CSS. См. этот пост для лучшего выделения текста в Puppeteer.

После закрытия баннер постепенно анимируется, поэтому, если он не завершится к моменту создания снимка экрана, вы все равно его увидите.

При автоматизации браузера за пределами среды тестирования нет никаких обязательств действовать так, как действовал бы человек. Неанимированный способ избавиться от баннера — просто мгновенно удалить его из DOM с помощью JS:

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

const url = "<Your URL>";

(async function main() {
  let browser;

  try {
    browser = await puppeteer.launch({
      defaultViewport: {
        width: 1920,
        height: 1080,
      },
    });
    const [page] = await browser.pages();
    const response = await page.goto(url, {waitUntil: "networkidle2"});
    const banner = await page.waitForSelector(".cookie-notice");
    await banner.evaluate(el => el.remove());
    const path = new Date().toISOString() + ".png";
    await page.screenshot({path, fullPage: true});
  } catch (err) {
    console.error(err);
  }
  finally {
    await browser?.close();
  }
})();

На других сайтах помните, что баннер может находиться в iframe или в теневом корне, поэтому не ожидается, что это будет серебряная пуля, которая будет работать с любым баннером.

В случаях, когда .remove() не запускает необходимые события и вы вынуждены нажать кнопку, вы можете использовать page.waitForFunction для опроса, пока элемент не будет удален из DOM или не скрыт, как еще один способ избежать создания снимка экрана во время анимации. все еще продолжается после щелчка.

Другие примечания о вашем коде:

  • ["domcontentloaded", "networkidle2"]может быть просто "networkidle2". "domcontentloaded" гарантированно разрешится к тому времени, когда "networkidle2" это сделает.
  • Обычно избегайте дескрипторов элементов, если вам не нужны доверенные события для тестирования. Для парсинга просто используйте ненадежный клик DOM, который более надежен, чем доверенный клик.

Если это не ответ на ваш вопрос, я предлагаю поделиться своим реальным сайтом, поскольку его специфическое поведение может иметь значение.

Также обратите внимание, что щелчок по баннеру cookie часто не нужен для очистки данных — обычно вы можете извлечь данные, не беспокоясь о видимости, сосредоточившись на ненадежных событиях DOM и перехвате сетевых запросов. Однако если ваш реальный вариант использования — это снимок экрана, то вы поступаете правильно.

Большое спасибо. Вчера я узнал с моим другом, что, как вы говорите, после щелчка и создания скриншота должна быть задержка. Забавно то, что я подумал об этом и добавил setTimeout из узла, но не поставил await перед этим, поэтому он просто запускался в конце скрипта: D Что касается удаления его из DOM, ситуация такова, что я очищаю несколько сайтов и у каждого есть разные селекторы, поэтому я пришел к выводу, что нажать «Принять» на всех из них проще, потому что это либо Accept, либо Accept All кнопка. Но я ценю ваш стиль, сэр.

user24820471 02.05.2024 13:19

Также спасибо за улучшение моего кода, я посмотрю, как использовать селекторы текста в соответствии с новейшими стандартами.

user24820471 02.05.2024 13:20

Другие вопросы по теме