Сохранение результатов в MongoDB

Для работы с Puppeteer и MongoDB необходимо подготовить проект. Предполагается, что используется Node.js последней версии. В терминале создается директория проекта и инициализируется package.json:

mkdir puppeteer-mongo
cd puppeteer-mongo
npm init -y

Устанавливаются зависимости:

npm install puppeteer mongodb dotenv
  • puppeteer — библиотека для управления браузером Chrome или Chromium через API.
  • mongodb — официальный драйвер для работы с MongoDB.
  • dotenv — управление конфигурацией через .env файл.

Создается файл .env для хранения конфиденциальных данных:

MONGO_URI=mongodb://localhost:27017
DB_NAME=testdb
COLLECTION_NAME=results

Подключение к MongoDB

Для сохранения данных необходимо установить соединение с MongoDB. Используется асинхронная функция для подключения:

const { MongoClient } = require(&
require('dotenv').config();

async function connectToMongo() {
    const client = new MongoClient(process.env.MONGO_URI);
    await client.connect();
    const db = client.db(process.env.DB_NAME);
    const collection = db.collection(process.env.COLLECTION_NAME);
    return { client, collection };
}

Ключевые моменты:

  • MongoClient создаёт клиентское соединение.
  • db.collection возвращает коллекцию для операций insert, update и find.
  • Важно закрывать соединение после работы через client.close().

Сбор данных с помощью Puppeteer

Puppeteer позволяет автоматизировать браузерные действия и извлекать данные со страниц. Пример скрипта для парсинга новостей:

const puppeteer = require('puppeteer');

async function scrapeData(url) {
    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });

    const data = await page.evaluate(() => {
        const items = Array.from(document.querySelectorAll('.news-item'));
        return items.map(item => ({
            title: item.querySelector('h2').innerText.trim(),
            link: item.querySelector('a').href,
            date: item.querySelector('.date').innerText.trim()
        }));
    });

    await browser.close();
    return data;
}

Особенности:

  • headless: true запускает браузер в фоновом режиме.
  • waitUntil: ‘networkidle2’ гарантирует загрузку всех ресурсов страницы.
  • page.evaluate позволяет выполнять код внутри контекста браузера.

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

После получения данных их нужно записать в базу. Создается функция для вставки массива документов:

async function saveToMongo(data) {
    const { client, collection } = await connectToMongo();
    try {
        if (data.length > 0) {
            const result = await collection.insertMany(data);
            console.log(`${result.insertedCount} документов добавлено`);
        } else {
            console.log('Нет данных для вставки');
        }
    } catch (error) {
        console.error('Ошибка при сохранении в MongoDB:', error);
    } finally {
        await client.close();
    }
}

Важные моменты:

  • insertMany вставляет несколько документов за один запрос, что эффективнее, чем insertOne в цикле.
  • Обязательно обрабатывать ошибки и закрывать соединение через finally.

Автоматизация полного процесса

Можно объединить сбор данных и сохранение в одной функции:

async function main() {
    const url = 'https://example.com/news';
    const scrapedData = await scrapeData(url);
    await saveToMongo(scrapedData);
}

main().catch(console.error);

Преимущества такого подхода:

  • Четкая структура: сбор данных и запись в базу разделены на функции.
  • Легко расширять для нескольких сайтов или разных коллекций.
  • Простое логирование количества вставленных документов.

Управление дубликатами и обновлениями

При регулярном парсинге важно избегать дублирования. MongoDB поддерживает уникальные индексы:

async function ensureIndex() {
    const { client, collection } = await connectToMongo();
    try {
        await collection.createIndex({ link: 1 }, { unique: true });
        console.log('Индекс для уникальных ссылок создан');
    } finally {
        await client.close();
    }
}

Для обновления существующих документов можно использовать updateOne с опцией upsert: true:

await collection.updateOne(
    { link: item.link },
    { $set: item },
    { upsert: true }
);

Таким образом, новые статьи добавляются, а существующие — обновляются без дубликатов.

Практические советы

  • Разделять парсинг, обработку и сохранение данных на отдельные модули.
  • Добавлять таймауты и try/catch при работе с Puppeteer для устойчивости к падениям страниц.
  • Логировать результаты и ошибки для последующего анализа.
  • Использовать .env для конфиденциальных данных, не хранить URI и пароли в коде.
  • При больших объемах данных рассматривать пакетную вставку (bulkWrite) для оптимизации производительности.

Сочетание Puppeteer и MongoDB позволяет создавать автоматизированные системы сбора данных, сохранять их структурировано и поддерживать актуальность через обновления и уникальные индексы. Такой подход применяется в тестировании веб-приложений, мониторинге сайтов и аналитике контента.