web-dev-qa-db-fra.com

Gérer le marionnettiste pour la mémoire et les performances

J'utilise marionnettiste pour gratter certaines pages, mais je suis curieux de savoir comment gérer cela en production pour une application de nœud. Je vais gratter jusqu'à 500 000 pages par jour, mais ces travaux de raclage se feront à des intervalles aléatoires, donc ce n'est pas une seule file d'attente que je peux parcourir.

Ce que je me demande, est-il préférable d'ouvrir un navigateur, d'aller à la page, puis de fermer le navigateur entre chaque travail? Ce qui, je suppose, serait beaucoup plus lent, mais peut-être mieux gérer la mémoire?

Ou dois-je ouvrir un navigateur global au démarrage de l'application, puis aller à la page et avoir un moyen de vider cette page lorsque j'en ai fini (par exemple, fermer tous les onglets en chrome, mais pas fermer le chrome), puis juste rouvrir une nouvelle page quand j'en ai besoin? De cette façon, il semble que ce serait plus rapide, mais pourrait potentiellement consommer beaucoup de mémoire.

Je n'ai jamais travaillé avec cette bibliothèque, en particulier dans un environnement de production, donc je ne sais pas s'il y a des choses à surveiller.

7
jeremywoertink

Si vous grattez 500 000 pages par jour (environ une page toutes les 0,1728 seconde ), alors je recommanderais d'ouvrir une nouvelle page dans une session de navigateur existante plutôt que d'ouvrir une nouvelle session de navigateur pour chaque page.

Vous pouvez ouvrir et fermer un Page en utilisant la méthode suivante:

const page = await browser.newPage();
await page.close();

Si vous décidez d'utiliser un Navigateur pour votre projet, je m'assurerais de mettre en œuvre des procédures de gestion des erreurs pour m'assurer que si le programme plante, vous avez un temps d'arrêt minimal pendant que vous créez un nouveau Page , Navigateur , ou BrowserContext .

5
Grant Miller

Vous souhaitez probablement créer un pool de plusieurs instances Chromium avec des navigateurs indépendants. L'avantage est que lorsqu'un navigateur plante, tous les autres travaux peuvent continuer à fonctionner. L'avantage d'un navigateur (avec plusieurs pages) est un léger avantage de mémoire et de CPU et les cookies sont partagés entre vos pages.

Pool d'instances de marionnettistes

La bibliothèque puppteer-cluster (clause de non-responsabilité: je suis l'auteur) crée un pool de navigateurs ou de pages pour vous. Il s'occupe de la création, du traitement des erreurs, du redémarrage du navigateur, etc. pour vous. Ainsi, vous pouvez simplement mettre en file d'attente les tâches/URL et la bibliothèque s'occupe de tout le reste.

Exemple de code

const { Cluster } = require('puppeteer-cluster');

(async () => {
    const cluster = await Cluster.launch({
        concurrency: Cluster.CONCURRENCY_BROWSER, // use one browser per worker
        maxConcurrency: 4, // cluster with four workers
    });

    // Define a task to be executed for your data (put your "crawling code" in here)
    await cluster.task(async ({ page, data: url }) => {
        await page.goto(url);
        // ...
    });

    // Queue URLs when the cluster is created
    cluster.queue('http://www.google.com/');
    cluster.queue('http://www.wikipedia.org/');

    // Or queue URLs anytime later
    setTimeout(() => {
        cluster.queue('http://...');
    }, 1000);
})();

Vous pouvez également mettre les fonctions en file d'attente directement au cas où vous auriez une tâche différente à faire. Normalement, vous fermeriez le cluster une fois que vous avez terminé via cluster.close(), mais vous êtes libre de le laisser rester ouvert. Vous trouverez un autre exemple pour un cluster qui obtient des données lorsqu'une demande arrive dans le référentiel .

7
Thomas Dondorf