@TANK_IST

Как запустить параллельный парсинг страниц на node.js?

Сайтов будет много, нужно чтобы страницы загружались параллельно и результат выводился одним массивом.
Написал такой код:
index.js
const puppeteer = require('puppeteer');
const yargs = require('yargs');
const sites = [];
sites['amazon'] = require('./amazon.js');
sites['ebay'] = require('./amazon.js');
const data = [];


puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--window-size=1920,1080', '--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3312.0 Safari/537.36"']
}).then(async browser => {
    for (i in sites) {
        data.push( await sites[i].parse(browser));
    }

    console.log(data);

    await browser.close();
}).catch(function (error) {
    console.error(error);
});


amazon.js
const yargs = require('yargs');

let parse = async (browser) => {
    const page = await browser.newPage();
    await page.setJavaScriptEnabled(false);
    await page.setRequestInterception(true);
    page.on('request', (request) => {
        if (['image', 'stylesheet', 'font', 'script'].indexOf(request.resourceType()) !== -1) {
            request.abort();
        } else {
            request.continue();
        }
    });
    await page.goto("https://www.amazon.com/s?k="+ yargs.argv.search +"&rh=p_n_condition-type%3ANew");
    await page.waitForSelector('body');

    let products = await page.evaluate(() => {
        let divs = document.body.querySelectorAll('.s-search-results>div[data-asin]');
        let items = [];

        divs.forEach(item => {
            let price = item.querySelector('.a-price:not([data-a-strike]) .a-offscreen');
            let priceOld = item.querySelector('.a-price[data-a-strike] .a-offscreen');

            price = price ? price.innerText : null;
            priceOld = priceOld ? priceOld.innerText : null;

            items.push({
                asin: item.getAttribute('data-asin'),
                price: price,
                priceOld: priceOld,
                title: item.querySelector('h2').innerText,
                img: item.querySelector('img').getAttribute('src')
            });
        });

        return items;
    });

    return products;
};

module.exports = {
    parse
};


Сейчас он работает, но он синхронный.
Ноду запускаю через php.
Спасибо!
  • Вопрос задан
  • 276 просмотров
Пригласить эксперта
Ответы на вопрос 1
IDONTSUDO
@IDONTSUDO
ЧСВ программистов идет в комплекте с первой IDE.
-нужно чтобы страницы загружались параллельно и результат выводился одним массивом.

Это означает, что вы хотите синхронный код. Который вы можете контролировать.

Здесь достаточно хорошее обьяснение того как нода работает

Но так же можно запустить, node cluster. На каждую страницу которую нужно спарсить делать свой отдельный поток. И класть все данные со спрасенных страниц в базу данных. А после смерять это все. Но это такое себе, так как производительность будет зависить от того сколько у вас ядер у процессора.

Если вы хотите поступить таким образом. Смотрите по документации в сторону Event: 'message'.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы