Не можете использовать циклы for с несколькими очередями кластера в кукольном кластере? - PullRequest
0 голосов
/ 01 августа 2020

Каков правильный метод использования циклов внутри функции очереди кластера?

У меня есть массив из 4656 URL-адресов, для индивидуального посещения которых требуется около 77 минут с одним экземпляром кукловода для каждого URL-адреса посещена, страница оценивается, и для получения всех элементов в определенном классе используется a for l oop.

Я хочу существенно сократить это время, так что кукловод-кластер определенно привлек мой интерес.

Пытаясь использовать его, я сначала подготовил URL 4656, чтобы их могли посещать 8 одновременных экземпляров / кластеров кукловода. Я сделал это, разделив 4656 URL-адресов на 8 массивов, содержащих по 582 URL-адреса каждый.

const concurrentGroupLength = Math.round(urlArray.length / 8);
const concurrentGroup1 = urlArray.slice(0, concurrentGroupLength);
const concurrentGroup2 = urlArray.slice(concurrentGroupLength, concurrentGroupLength * 2);
const concurrentGroup3 = urlArray.slice(concurrentGroupLength * 2, concurrentGroupLength * 3);
const concurrentGroup4 = urlArray.slice(concurrentGroupLength * 3, concurrentGroupLength * 4);
const concurrentGroup5 = urlArray.slice(concurrentGroupLength * 4, concurrentGroupLength * 5);
const concurrentGroup6 = urlArray.slice(concurrentGroupLength * 5, concurrentGroupLength * 6);
const concurrentGroup7 = urlArray.slice(concurrentGroupLength * 6, concurrentGroupLength * 7);
const concurrentGroup8 = urlArray.slice(concurrentGroupLength * 7, concurrentGroupLength * 8 + 1);

Затем я запустил puppeteer-cluster, установил maxConcurrency 8 и поставил в очередь 8 кластеров для каждого массива URL *. 1010 *

const results = [];

(async () => {
        const cluster = await Cluster.launch({
            concurrency: Cluster.CONCURRENCY_CONTEXT,
            maxConcurrency: 8,
            timeout: 960000,
        });

        const getPageData = async ({page, data: urls}) => {
            for (i = 0; i < urls.length; i++) {
                await page.goto(urls[i], {waitUntil: 'networkidle2'});

                let titleArray = await page.evaluate(() => {
                    let pageTitles = [];
                    for (j = 0; j < document.getElementsByClassName('canvas')[0].getElementsByClassName('genre scanme').length; j++) {
                        pageTitles.push(document.getElementsByClassName('canvas')[0].getElementsByClassName('genre scanme')[j].innerText);
                    }
                    return pageTitles;
                });

                results.push({titles: titleArray});
                console.log(results)
            }
        };

        cluster.queue(concurrentGroup1, getPageData);
        cluster.queue(concurrentGroup2, getPageData);
        cluster.queue(concurrentGroup3, getPageData);
        cluster.queue(concurrentGroup4, getPageData);
        cluster.queue(concurrentGroup5, getPageData);
        cluster.queue(concurrentGroup6, getPageData);
        cluster.queue(concurrentGroup7, getPageData);
        cluster.queue(concurrentGroup8, getPageData);

        cluster.on('taskerror', (err, data, willRetry) => {
            if (willRetry) {
                console.warn(`Encountered an error while crawling ${data}. ${err.message}\nThis job will be retried`);
            } else {
                console.error(`Failed to crawl ${data}: ${err.message}`);
            }
        });

        await cluster.idle();
        await cluster.close();
    })();

Однако кукловод-кластер не может запустить для l oop одновременно в функции. For l oop дает сбой и превышает максимальное количество итераций, определенное параметром i < urls.length, которое всегда равно 582. Это возвращает undefined для каждой итерации, превышающей 582, что, как оказалось, было таким же количеством запущенных кластеров в очереди.

Это происходит потому, что он пытается посетить страницы с await page.goto(urls[i], {waitUntil: 'networkidle2'});, которые, очевидно, не существуют, потому что urls[i] во время этих превышенных итераций было равно undefined.

См. Видео, которое я сделал ниже, иллюстрирующий эту проблему. Журналы, которые вы видите в видео, относятся к console.log(results), которое вы можете найти в скрипте.

https://www.youtube.com/watch?v=G0pHypc7SBs&feature=youtu.be

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...