Не удается взаимодействовать с Iframe, даже когда найден Puppeteer

Вопрос или проблема

Прежде чем объяснить свой код, хочу отметить, что он работал последние три года… так что что-то изменилось либо в последнем обновлении pup, либо на самом сайте.

Целевой URL: https://ecomm.one-line.com/one-ecom/manage-shipment/cargo-tracking

Целевой Iframe: document.querySelector(“#IframeCurrentEcom”)

Я пробовал:

попытка 1

const frame = await page.waitForFrame("https://ecomm.one-line.com/ecom/CUP_HOM_3301.do")

попытка 2, которую я использовал и которая больше не работает

const frame = await page.waitForSelector("#IframeCurrentEcom")
const iframeContext = frame.contentFrame();

попытка 3

const frame = await page.$("#IframeCurrentEcom");
const handle = frame.frameElement();

попытка 4: [3], потому что это целевой iframe среди всех iframes на этой странице

page.frames()[3]

Все вышеперечисленное может получить объект Iframe, но при попытке использовать evaluate, type… это просто не взаимодействует.

Единственный способ, который я нашел, чтобы это работало, был следующим

const cleanedReferences="123";
await parent.page.evaluate((cleanedReference) => {
        const frame = document.getElementById("IframeCurrentEcom") as HTMLIFrameElement;
        // @ts-ignore
        frame.contentWindow.document.querySelector("#searchName").value = cleanedReference;
        // @ts-ignore
        frame.contentWindow.document.querySelector("#btnSearch").click();
        // console.log(frame.contentWindow.document.querySelector("#searchName"))
    }, cleanedReference)

Это означает, что мне придется извлекать все данные внутрь evaluate. У меня с этим нет проблем, но я хотел бы понять, что не так со всеми другими подходами…

Ответ или решение

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

Возможные причины проблемы

  1. Изменения на сайте: Существует вероятность, что сам веб-сайт изменил структуру или поведение своих iframe. Например, может измениться URL iframe или запрещены некоторые кросс-доменные запросы.

  2. Изменения в версии Puppeteer: Если вы обновили Puppeteer, возможно, произошли изменения в API или в способах работы с iframe.

  3. CORS и политика безопасности контента: Если iframe загружает страницу с другого домена, могут возникнуть проблемы с политикой кросс-доменных запросов (CORS), что может ограничивать доступ к контенту iframe.

Решения

1. Проверка доступности iframe и его контента

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

const frame = await page.frames().find(f => f.url().includes("CUP_HOM_3301.do"));
if (frame) {
    // Доступ к iframe.
} else {
    console.error("Iframe не найден или недоступен.");
}

2. Исправление метода доступа к iframe

Если iframe загружается, но вы не можете взаимодействовать с его элементами, попробуйте использовать waitForSelector на самом iframe, а затем доступ к нему через contentFrame:

const frameHandle = await page.waitForSelector('#IframeCurrentEcom');
const frame = await frameHandle.contentFrame();

if (frame) {
    const searchInput = await frame.waitForSelector("#searchName");
    await searchInput.type("123");

    const searchButton = await frame.waitForSelector("#btnSearch");
    await searchButton.click();
} else {
    console.error("Не удалось получить контекст iframe.");
}

3. Задержка перед взаимодействием

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

await frame.waitForNavigation();  // Или waitForSelector для конкретного элемента

4. Запуск скрипта в контексте iframe

Если ничего не помогает, как вы уже сделали, можно выполнить код непосредственно внутри контекста iframe с помощью page.evaluate. Обратите внимание, что это ограничивает доступ к переменным вне этого контекста, однако для простых операций это может быть наилучшим решением.

await page.evaluate((cleanedReference) => {
    const frame = document.getElementById("IframeCurrentEcom");
    const innerDoc = frame.contentDocument || frame.contentWindow.document;

    innerDoc.querySelector("#searchName").value = cleanedReference;
    innerDoc.querySelector("#btnSearch").click();
}, cleanedReferences);

Заключение

Ваша проблема, скорее всего, связана с изменениями на сайте или в Puppeteer. Проверяйте доступность iframe, используйте корректный метод взаимодействия с его контентом и не забывайте про задержки загрузки. Если ничего не помогает, взаимодействие через evaluate остается рабочим решением. Надеюсь, это поможет вам разобраться с вашей проблемой!

Оцените материал
Добавить комментарий

Капча загружается...