MySQL интеграция

Для начала необходимо установить Puppeteer и клиент для работы с MySQL в Node.js. Puppeteer обеспечивает управление браузером Chromium или Chrome через API, а mysql2 или mysql предоставляет возможность работы с базой данных MySQL.

npm install puppeteer mysql2

После установки создается соединение с базой данных:

const mysql = require(&

const connection = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'testdb'
});

Использование mysql2/promise позволяет применять асинхронные функции и await, что упрощает интеграцию с Puppeteer.


Запуск браузера и взаимодействие с страницей

Puppeteer предоставляет методы для запуска браузера и работы с вкладками:

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');

Ключевые методы для извлечения данных:

  • page.(selector) < /code > —возвращаетпервыйэлементпоселектору. < /li >  < li >  < code > page.$(selector) — возвращает массив элементов по селектору.
  • page.evaluate(callback) — выполняет функцию в контексте страницы.

Пример извлечения данных из таблицы:

const data = await page.evaluate(() => {
    const rows = Array.from(document.querySelectorAll('table tr'));
    return rows.map(row => {
        const cells = row.querySelectorAll('td');
        return Array.from(cells, cell => cell.innerText);
    });
});

Сохранение данных в MySQL

После извлечения данных их можно вставлять в таблицу. Рекомендуется использовать подготовленные запросы для защиты от SQL-инъекций:

const query = 'INSERT INTO users (name, email) VALUES (?, ?)';

for (const row of data) {
    await connection.execute(query, [row[0], row[1]]);
}

Для больших массивов данных эффективнее использовать пакетные вставки:

const values = data.map(row => [row[0], row[1]]);
await connection.query('INSERT INTO users (name, email) VALUES ?', [values]);

Обработка динамического контента

Многие страницы используют JavaScript для загрузки данных после загрузки DOM. Puppeteer позволяет ожидать появления элементов:

await page.waitForSelector('table tr');

Для случаев с пагинацией можно организовать цикл:

let hasNext = true;
while (hasNext) {
    const rows = await page.$$eval('table tr', trs =>
        trs.map(tr => Array.from(tr.cells, td => td.innerText))
    );

    // Вставка в MySQL
    await connection.query('INSERT INTO users (name, email) VALUES ?', [rows.map(r => [r[0], r[1]])]);

    const nextButton = await page.$('button.next');
    if (nextButton) {
        await nextButton.click();
        await page.waitForSelector('table tr');
    } else {
        hasNext = false;
    }
}

Логирование и обработка ошибок

Для стабильной интеграции важно логировать успешные операции и обрабатывать ошибки:

try {
    await connection.execute(query, [row[0], row[1]]);
    console.log(`Запись ${row[0]} успешно добавлена`);
} catch (error) {
    console.error(`Ошибка при вставке: ${error.message}`);
}

Также можно обернуть весь процесс в try/catch с финальной очисткой ресурсов:

try {
    // Основная логика Puppeteer и MySQL
} finally {
    await browser.close();
    await connection.end();
}

Работа с транзакциями

Для критичных операций рекомендуется использовать транзакции:

await connection.beginTransaction();

try {
    for (const row of data) {
        await connection.execute(query, [row[0], row[1]]);
    }
    await connection.commit();
} catch (error) {
    await connection.rollback();
    console.error('Транзакция откатана из-за ошибки:', error.message);
}

Транзакции обеспечивают целостность данных при массовых вставках и предотвращают частичные записи в случае ошибок.


Советы по производительности

  1. Пакетная вставка данных — уменьшает количество SQL-запросов.
  2. Использование headless режима — снижает нагрузку на систему.
  3. Ограничение параллельных операций — избегает блокировок MySQL.
  4. Кэширование повторяющихся данных — снижает количество повторных обращений к странице.

Пример полного сценария

const puppeteer = require('puppeteer');
const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'password',
        database: 'testdb'
    });

    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    await page.goto('https://example.com');

    await page.waitForSelector('table tr');

    const data = await page.$$eval('table tr', trs =>
        trs.map(tr => Array.from(tr.cells, td => td.innerText))
    );

    const query = 'INSERT INTO users (name, email) VALUES (?, ?)';
    await connection.beginTransaction();
    try {
        for (const row of data) {
            await connection.execute(query, [row[0], row[1]]);
        }
        await connection.commit();
    } catch (error) {
        await connection.rollback();
        console.error(error);
    } finally {
        await browser.close();
        await connection.end();
    }
})();

Этот пример демонстрирует полный цикл: открытие страницы, извлечение данных, сохранение в MySQL с обработкой ошибок и использованием транзакций.