Newer
Older
vue-indexer / index.js
const puppeteer = require('puppeteer');
const url = require('url');
const fs = require('fs');

// Хранение уникальных ссылок и их метаданных
let visitedUrls = new Set();
let pagesMetadata = [];

// Функция для извлечения всех ссылок с текущей страницы
async function getLinksFromPage(page, currentUrl) {
    const links = await page.$$eval('a', anchors => anchors.map(a => a.href));
    const sameDomainLinks = links.filter(link => {
        const parsedLink = url.parse(link);
        return parsedLink.hostname === url.parse(currentUrl).hostname;
    });
    return sameDomainLinks;
}

// Функция для извлечения метаданных (title, description, keywords)
async function getMetadataFromPage(page) {
    const title = await page.title();
    const description = await page.$eval('meta[name="description"]', el => el.content, { defaultValue: '' }).catch(() => '');
    const keywords = await page.$eval('meta[name="keywords"]', el => el.content, { defaultValue: '' }).catch(() => '');
    return { title, description, keywords };
}

async function getLargestPictureImage(page) {
    // Получаем все теги <picture> и их изображения
    const pictures = await page.$$eval('picture', pictureTags => {
        return pictureTags.map(picture => {
            const img = picture.querySelector('img');
            if (img) {
                return {
                    src: img.currentSrc || img.src,
                    width: img.naturalWidth,
                    height: img.naturalHeight
                };
            }
            return null;
        }).filter(img => img !== null);
    });

    if (pictures.length === 0) {
        return ''; // Если нет картинок в <picture>, возвращаем пустую строку
    }

    // Сортируем изображения по площади (width * height) и выбираем самое большое
    const largestPicture = pictures.reduce((largest, current) => {
        const currentArea = current.width * current.height;
        const largestArea = largest.width * largest.height;
        return currentArea > largestArea ? current : largest;
    });

    return largestPicture.src; // Возвращаем URL самого крупного изображения
}

// Функция для поиска изображения обложки
async function getCoverImage(page) {
    // 1. Попробуем найти изображение через meta og:image
    const ogImage = await page.$eval('meta[property="og:image"]', el => el.content, { defaultValue: '' }).catch(() => '');
    
    if (ogImage) {
        return ogImage; // Если нашли og:image, возвращаем его
    }

    return getLargestPictureImage(page);
}

// Основная функция рендеринга и парсинга
async function renderAndParsePage(currentUrl, depth = 0, maxDepth = 3) {
    if (depth > maxDepth) return;

    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    try {
        // Открываем страницу
        await page.goto(currentUrl, { waitUntil: 'networkidle2' });
        console.log(`Рендер страницы: ${currentUrl}`);

        // Получаем метаданные
        const metadata = await getMetadataFromPage(page);
        
        // Получаем изображение обложки
        const coverImage = await getCoverImage(page);

        // Добавляем информацию о странице в массив метаданных
        pagesMetadata.push({
            url: currentUrl,
            title: metadata.title,
            description: metadata.description,
            keywords: metadata.keywords,
            coverImage: coverImage // Добавляем обложку в метаданные
        });

        // Находим все ссылки на текущей странице
        const links = await getLinksFromPage(page, currentUrl);

        // Обрабатываем каждую ссылку
        for (let link of links) {
            if (!visitedUrls.has(link)) {
                visitedUrls.add(link);
                console.log(`Найден путь: ${link}`);
                await renderAndParsePage(link, depth + 1, maxDepth); // Рекурсивно обрабатываем новые ссылки
            }
        }

    } catch (error) {
        console.error(`Ошибка при рендере страницы: ${currentUrl}`, error);
    } finally {
        await browser.close();
    }
}

// Запуск скрипта с главной страницы
const urls = [
    'https://neiromidin.lbp.open.olainfarm.kz',
    'https://neiromidin.stroke.open.olainfarm.kz',
];

// Запуск скрипта
(async () => {
    for(let url of urls) {
        await renderAndParsePage(url);
    }

    // Записываем метаданные в файл
    fs.writeFileSync('pages_metadata.json', JSON.stringify(pagesMetadata, null, 2), 'utf-8');
    console.log('Метаданные страниц успешно сохранены в pages_metadata.json');
})();