Как правильно использовать Java в Tampermonkey для сбора данных при открытии новой вкладки?

Я сталкиваюсь с проблемой уже несколько дней, и вот что у меня есть: 

1. В первом варианте мой скрипт корректно собирает данные при обновлении определённой страницы. 
2. Во втором варианте (который мне нужен) я пытаюсь сделать так, чтобы скрипт открывал новую вкладку и собирал данные на этой вкладке. Однако вместо ожидаемых 2 значений я получаю 42 и больше. Я перепробовал различные подходы, но ничего не помогает. 

Недавно мне пришла в голову идея обновлять страницу после перехода и её загрузки, но и это не дало результатов.

Вот фрагмент кода, который я использую: 

```javascript
function visitLinksSequentially(links, newTab) {
    let index = 0;
    function visitNextLink() {
        if (index < links.length) {
            const link = links[index];
            index++;
            newTab.location.href = link;
            // Здесь мне нужно подождать ПОЛНУЮ загрузку страницы и только потом приступать к сборке
            waitForDOMReady(() => {
                setTimeout(() => {
                    // ТУТ ПЕРЕМЕННАЯ ДЛЯ ИЗВЛЕЧЕНИЯ ДАННЫХ();
                }, 200);
            });
            newTab.addEventListener('load', visitNextLink);
        } else {
            newTab.close(); 
        }
    }
    visitNextLink();
}
```

Как я могу решить эту проблему?
  • 17 ноября 2024 г. 9:23
Ответы на вопрос 2
Использование Tampermonkey для сбора данных с нескольких страниц в новых вкладках может быть непростой задачей, особенно когда дело касается правильного ожидания загрузки страниц и извлечения данных. В вашем случае проблема, скорее всего, связана с тем, что вы не учитываете состояние новой вкладки после каждой загрузки.

Ниже приведен пример того, как можно улучшить ваш скрипт, чтобы он корректно обрабатывал загрузку страниц и собирал данные:

```javascript
// Функция для ожидания полной загрузки DOM
function waitForDOMReady(callback) {
    const checkReady = () => {
        if (document.readyState === "complete") {
            callback();
        } else {
            setTimeout(checkReady, 100);
        }
    };
    checkReady();
}

// Функция для сбора данных
function extractData() {
    // Ваша логика для извлечения данных из текущей страницы
    // Например:
    let data = document.querySelector("selector").innerText; // замените на собственный селектор
    return data;
}

// Основная функция для последовательного посещения ссылок
function visitLinksSequentially(links) {
    let index = 0;
    const newTab = window.open(); // открываем новую вкладку

    function visitNextLink() {
        if (index < links.length) {
            const link = links[index];
            index++;
            newTab.location.href = link;

            // Ждем, пока страница полностью загрузится
            newTab.addEventListener('load', () => {
                waitForDOMReady(() => {
                    // Извлекаем данные
                    const data = extractData();
                    console.log(data); // Здесь можно сохранить данные или обработать их как нужно
                    visitNextLink(); // Переходим к следующей ссылке
                });
            });
        } else {
            newTab.close(); // Закрываем вкладку, когда все ссылки обработаны
        }
    }

    visitNextLink();
}

// Пример использования
const links = ["https://example.com/page1", "https://example.com/page2"]; // Ваши ссылки
visitLinksSequentially(links);
```

### Описание изменений:

1. **Логика ожидания загрузки страницы**: Мы добавили обработчик события `load` для новой вкладки, который будет ожидать, пока она полностью загрузится, прежде чем продолжать обработку.

2. **Извлечение данных**: Узлы для извлечения данных теперь помещены в отдельной функции `extractData()`, что позволит вам легко адаптировать логику извлечения в зависимости от структуры загружаемой страницы.

3. **Открытие новой вкладки**: Мы открываем новую вкладку в начале и добавляем слушателя события `load`, чтобы ожидать ее полной загрузки перед выполнением дальнейших действий.

4. **Закрытие новой вкладки**: Вкладка закроется только после обработки всех ссылок.

Теперь это должно дать вам возможность извлекать данные из каждой страницы загруженной в новой вкладке, исключив дублирование данных. Убедитесь, что вы правильно настраиваете селекторы в функции `extractData()`, чтобы получать только те данные, которые вам нужны.
function visitLinksSequentially(links) {
    let index = 0;

    function waitForPageLoad(newTab, callback) {
        // ждем полную загрузку
        newTab.addEventListener('load', function onLoad() {
            newTab.removeEventListener('load', onLoad); 
            callback(); 
        });
    }

    function extractData(newTab, callback) {
        // логика для извлечения данных
        const extractedData = newTab.document.querySelectorAll('SELECTOR_YOUR_DATA'); 
        console.log('Извлечённые данные:', extractedData); 
        callback(); 
    }

    function visitNextLink() {
        if (index < links.length) {
            const link = links[index];
            index++;
            const newTab = window.open(); // открыли новую вкладку

            newTab.location.href = link;

            waitForPageLoad(newTab, () => {
                setTimeout(() => {
                    extractData(newTab, () => {
                        newTab.close(); // закрыли
                        visitNextLink(); // пошли дальше
                    });
                }, 1000); 
            });
        } else {
            console.log('Good job bro!');
        }
    }

    visitNextLink();
}
Похожие вопросы