Abonnements
PRODUIT
SOLUTIONS
par cas d'utilisation
AI Gestion du leadFacturationRéseaux SociauxGestion de projetGestion des donnéespar industrie
en savoir plus
BlogGabaritsVidéosYoutubeRESSOURCES
COMMUNAUTÉS ET RÉSEAUX SOCIAUX
PARTENAIRES
page.evaluate()
est une clé Marionnettiste méthode permettant d'exécuter JavaScript directement dans le contexte du navigateur. Elle fait le lien Node.js et le navigateur, permettant des tâches telles que la manipulation du DOM, l'extraction de données et l'automatisation de pages web dynamiques. Voici ce que vous devez savoir :
const title = await page.evaluate(() => document.title);
Cela récupère le titre de la page directement à partir du navigateur.
Fonctionnalité | Contexte de Node.js | Contexte du navigateur |
---|---|---|
Objets globaux | process , require |
window , document |
Emplacement du script | Machine locale | Page Web cible |
Accès API | API Node.js | API Web du navigateur |
Utilisez page.evaluate()
pour des tâches d'automatisation précises et efficaces, en particulier lorsque vous travaillez avec des sites Web riches en JavaScript.
Lorsque vous travaillez avec Puppeteer pour l'automatisation Web, il est essentiel de comprendre la distinction entre Contexte Node.js et de la contexte du navigateurCes deux environnements sont isolés, chacun avec ses propres règles d'exécution de code et d'échange de données.
Puppeteer opère dans deux environnements : le Contexte Node.js, où votre script principal s'exécute, et le contexte du navigateur, où se produisent les interactions avec la page web. Il s'agit de processus distincts, chacun disposant de sa propre machine virtuelle.
Voici une comparaison rapide de leurs principales caractéristiques :
Fonctionnalité | Contexte de Node.js | Contexte du navigateur |
---|---|---|
Objets globaux | process , require , __dirname |
window , document , localStorage |
Emplacement du script | Machine locale | Page Web cible |
Portée variable | Portée du script du marionnettiste | Portée du contexte de la page |
Accès API | API Node.js | API Web du navigateur |
Espace mémoire | Processus séparé | Processus du navigateur |
L'échange de données entre ces contextes implique une série d'étapes, s'appuyant fortement sur la sérialisation :
Function.prototype.toString()
.Principales limitesLes fonctions du navigateur ne peuvent pas accéder directement aux variables de la portée Node.js. Puppeteer propose des outils spécifiques pour répondre à ces défis :
page.evaluateHandle()
: Renvoie des références aux objets dans le contexte du navigateur.page.exposeFunction()
: Permet au navigateur d'appeler les fonctions Node.js.evaluateOnNewDocument()
: Exécute le code avant le chargement des scripts de page.Cependant, la sérialisation JSON peut supprimer certaines propriétés, notamment pour les objets complexes comme les nœuds DOM. Pour éviter ces problèmes, transmettez les données sous forme d'arguments de fonction plutôt que de vous fier aux variables Node.js.
La maîtrise de ces techniques de communication vous garantit de pouvoir utiliser page.evaluate
efficacement pour les tâches d'automatisation. Nous explorerons ensuite des exemples pratiques pour mettre ces concepts en pratique.
syntaxe:
await page.evaluate(pageFunction, ...args)
Paramètre | Type | Description |
---|---|---|
pageFonction | Fonction ou chaîne | Code JavaScript à exécuter dans le contexte du navigateur |
args | Paramètres facultatifs | Valeurs transmises de Node.js au contexte du navigateur |
Valeur de retour | Promesse | Résout avec la valeur de retour de la fonction |
Le pageFonction Il peut s'agir d'une fonction ou d'une chaîne contenant du code JavaScript. L'utilisation d'une fonction est généralement plus adaptée au débogage et Manuscrit Compatibilité. Voici quelques exemples pour illustrer son fonctionnement.
Exemples :
<h1>
directement depuis le DOM :const headingText = await page.evaluate(() => {
return document.querySelector('h1').textContent;
});
await page.evaluate((username, password) => {
document.getElementById('username').value = username;
document.getElementById('password').value = password;
document.querySelector('#login-form').submit();
}, 'myUsername', 'myPassword');
await page.evaluate(() => {
const div = document.createElement('div');
div.textContent = 'Added by Puppeteer';
document.body.appendChild(div);
return div.textContent;
});
Conseil de débogage : Utilisez la configuration suivante pour activer le débogage pendant le développement :
const browser = await puppeteer.launch({
headless: false,
slowMo: 100 // Adds a 100ms delay to each operation
});
Ensuite, nous allons plonger dans les techniques d’échange de données entre Node.js et les contextes de navigateur.
Lors du transfert de données avec page.evaluate
, s'en tenir aux valeurs sérialisables JSON pour les arguments d'entrée.
Voici une brève description des types de paramètres pris en charge :
Type de paramètre | Prise en charge? | Exemple |
---|---|---|
Primitives | ✓ Entièrement | 'text' , 42 , true |
Tableaux/Objets | ✓ Compatible JSON | { key: 'value' } , [1, 2, 3] |
Les fonctions | ✗ Pas directement | Utilisez page.exposeFunction |
Éléments DOM | ✓ Via JSHandle | Utilisez page.evaluateHandle |
Voyons maintenant comment ces valeurs sont renvoyées à partir du contexte du navigateur.
Lors de l'utilisation page.evaluate
Les valeurs renvoyées sont automatiquement sérialisées au format JSON. Voici comment cela fonctionne :
// Returning a simple value
const pageTitle = await page.evaluate(() => document.title);
// Returning a complex object
const metrics = await page.evaluate(() => ({
viewport: window.innerWidth,
scrollHeight: document.body.scrollHeight,
timestamp: Date.now()
}));
« En règle générale, si la valeur de retour de la fonction donnée est plus compliquée qu'un objet JSON (par exemple, la plupart des classes), alors
evaluate
renverra probablement une valeur tronquée (ou{}
). Cela est dû au fait que nous ne renvoyons pas la valeur de retour réelle, mais une version désérialisée résultant du transfert de la valeur de retour via un protocole vers Puppeteer.
Une fois la sortie récupérée, vous pourriez rencontrer des problèmes de sérialisation. Voici comment les résoudre.
Certains scénarios courants nécessitent des solutions de contournement spécifiques :
const bodyHandle = await page.$('body');
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose(); // Always clean up to avoid memory leaks
await page.exposeFunction('md5', text =>
crypto.createHash('md5').update(text).digest('hex')
);
const hash = await page.evaluate(async () => {
return await window.md5('test-string');
});
Si vous travaillez avec TypeScript, assurez-vous que votre transpileur est correctement configuré :
// tsconfig.json
{
"compilerOptions": {
"target": "es2018"
}
}
Ces stratégies vous aideront à gérer efficacement l’échange de données dans divers contextes.
Voici comment vous pouvez utiliser page.evaluate
dans des scénarios réels, accompagnés d'extraits de code pratiques.
Exemple : Récupération des détails du produit
Ce script collecte des détails tels que le titre, le prix, la note et l'état du stock à partir des fiches produits sur une page Web :
const productData = await page.evaluate(() => {
const products = Array.from(document.querySelectorAll('.product-card'));
return products.map(product => ({
title: product.querySelector('.title').textContent.trim(),
price: product.querySelector('.price').textContent.trim(),
rating: parseFloat(product.querySelector('.rating').dataset.value),
inStock: product.querySelector('.stock').textContent.includes('Available')
}));
});
Exemple : Extraction de données de table
Cette approche récupère les données d'une table en parcourant ses lignes et ses colonnes :
const tableData = await page.evaluate(() => {
const rows = Array.from(document.querySelectorAll('table tr'));
return rows.map(row => {
const columns = row.querySelectorAll('td');
return Array.from(columns, column => column.innerText);
});
});
Automatisation de base des formulaires
Voici comment remplir les champs du formulaire, déclencher des événements et soumettre le formulaire :
await page.evaluate(() => {
// Fill form fields
document.querySelector('#username').value = 'testuser';
document.querySelector('#password').value = 'secretpass';
// Trigger input events for dynamic forms
const event = new Event('input', { bubbles: true });
document.querySelector('#username').dispatchEvent(event);
// Submit form
document.querySelector('form').submit();
});
Gestion de formulaires complexes
Pour des tâches telles que la sélection d'options déroulantes ou la vérification de boutons radio :
await page.evaluate(() => {
// Select dropdown option
const select = document.querySelector('#country');
select.value = 'US';
select.dispatchEvent(new Event('change', { bubbles: true }));
// Check radio button
const radio = document.querySelector('input[value="express"]');
radio.checked = true;
radio.dispatchEvent(new Event('change', { bubbles: true }));
});
Exemple : défilement infini
Ce script fait défiler une page jusqu'à ce qu'il collecte au moins 100 éléments :
const items = await page.evaluate(async () => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const items = new Set();
while (items.size < 100) {
// Scroll to bottom
window.scrollTo(0, document.body.scrollHeight);
// Wait for new content
await delay(1000);
// Collect items
document.querySelectorAll('.item').forEach(item =>
items.add(item.textContent.trim())
);
}
return Array.from(items);
});
Exemple : gestion du contenu AJAX
Pour charger plus de contenu de manière dynamique, ce script clique sur un bouton « Charger plus » et attend que de nouveaux éléments apparaissent :
await page.evaluate(async () => {
// Click load more button
document.querySelector('#loadMore').click();
// Wait for content update
await new Promise(resolve => {
const observer = new MutationObserver((mutations, obs) => {
if (document.querySelectorAll('.item').length > 10) {
obs.disconnect();
resolve();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
});
Ces exemples illustrent la gestion de divers scénarios tels que le scraping, l'automatisation des formulaires et le contenu dynamique. Des ajustements peuvent être apportés en fonction de la structure et du comportement spécifiques de la page web utilisée.
Latenode intègre les fonctionnalités principales de Puppeteer à ses workflows d'automatisation, facilitant ainsi l'exécution de JavaScript directement dans le navigateur. page.evaluate
Les utilisateurs peuvent manipuler le DOM et extraire efficacement les données. Cette approche permet une intégration transparente de la gestion avancée des données et des opérations DOM dans l'environnement d'automatisation de Latenode.
Le module d'automatisation du navigateur de Latenode utilise page.evaluate
Pour gérer toutes les tâches, des tâches DOM simples aux exécutions JavaScript plus complexes. Voici son fonctionnement dans différents scénarios :
// Basic DOM interaction
await page.evaluate(() => {
const loginButton = document.querySelector('#login');
loginButton.click();
// Trigger a custom event
loginButton.dispatchEvent(new Event('customClick'));
});
// Processing data with exposed functions
await page.exposeFunction('processData', async (data) => {
// Process data in Node.js context
return transformedData;
});
await page.evaluate(async () => {
const rawData = document.querySelector('#data').textContent;
const processed = await window.processData(rawData);
return processed;
});
Latenode conserve également un journal de l'historique d'exécution, ce qui facilite le débogage des scripts.
Latenode est parfaitement équipé pour gérer le contenu dynamique et les tâches d'automatisation complexes. Voici un exemple de traitement de contenu dynamique sur une page :
const extractProductData = await page.evaluate(async () => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// Wait for dynamic content to load
while (!document.querySelector('.product-grid')) {
await delay(100);
}
return Array.from(document.querySelectorAll('.product'))
.map(product => ({
name: product.querySelector('.name').textContent,
price: product.querySelector('.price').textContent,
availability: product.querySelector('.stock').dataset.status
}));
});
Pour des opérations plus avancées, page.exposeFunction
permet une interaction transparente entre Node.js et le navigateur :
await page.exposeFunction('md5', text =>
crypto.createHash('md5').update(text).digest('hex')
);
const processedData = await page.evaluate(async () => {
const sensitiveData = document.querySelector('#secure-data').value;
return await window.md5(sensitiveData);
});
Pour conserver les références aux éléments DOM à travers les étapes, Latenode utilise page.evaluateHandle
:
const elementHandle = await page.evaluateHandle(() => {
return document.querySelector('.dynamic-content');
});
await page.evaluate(element => {
element.scrollIntoView();
}, elementHandle);
Ces techniques permettent à Latenode de gérer efficacement le contenu dynamique tout en maintenant des performances fiables. Pour les utilisateurs de l'offre Prime, la plateforme prend en charge jusqu'à 1.5 million d'exécutions de scénarios par mois, offrant ainsi des capacités d'automatisation étendues.
Lorsque vous travaillez avec page.evaluate
L'automatisation des navigateurs peut engendrer divers problèmes. Voici des solutions pratiques pour les résoudre et garantir une exécution plus fluide.
Configurez correctement vos paramètres TypeScript pour éviter les problèmes liés à la transpilation. Par exemple :
// Use direct, non-transpiled functions
await page.evaluate(() => {
document.querySelector('#button').click();
});
await page.evaluate(`(async () => {
document.querySelector('#button').click();
})()`);
Évitez de renvoyer des éléments DOM directement depuis page.evaluate
. Au lieu de cela, utilisez ElementHandle
pour une meilleure maniabilité :
// Incorrect: Returning a DOM element
const element = await page.evaluate(() => {
return document.querySelector('.dynamic-element');
});
// Correct: Using ElementHandle
const element = await page.evaluateHandle(() => {
return document.querySelector('.dynamic-element');
});
Les scripts peuvent s'exécuter avant le chargement complet de la page, ce qui peut entraîner des erreurs de synchronisation. Utilisez les stratégies suivantes pour gérer ces situations :
// Wait for navigation after an action
await Promise.all([
page.waitForNavigation(),
page.click('#submit-button')
]);
// Wait for a specific condition
await page.waitForFunction(() => {
const element = document.querySelector('.lazy-loaded');
return element && element.dataset.loaded === 'true';
}, { timeout: 5000 });
Pour les sites Web dynamiques, adoptez des mécanismes d'attente plus ciblés :
// Wait for specific network requests
await page.waitForResponse(
response => response.url().includes('/api/data')
);
// Ensure elements are both present and visible
await page.waitForSelector('.dynamic-content', {
visible: true,
timeout: 3000
});
Pour éviter les fuites de mémoire, gérez soigneusement les références DOM. Voici comment :
// Use and dispose ElementHandles
const handle = await page.evaluateHandle(() => {
return document.querySelector('.temporary-element');
});
await handle.evaluate(element => {
// Perform operations
});
await handle.dispose(); // Dispose of handle after use
Lorsque vous travaillez avec plusieurs éléments, transmettez les données en toute sécurité entre les contextes :
// Extract data from the DOM
const selector = '.product-price';
const price = await page.evaluate((sel) => {
const element = document.querySelector(sel);
return element ? element.textContent.trim() : null;
}, selector);
Pour les écouteurs d'événements, assurez-vous d'un nettoyage approprié pour éviter les gestionnaires persistants :
await page.evaluate(() => {
const handler = () => console.log('clicked');
const button = document.querySelector('#button');
button.addEventListener('click', handler);
// Store cleanup references
window._cleanupHandlers = window._cleanupHandlers || [];
window._cleanupHandlers.push(() => {
button.removeEventListener('click', handler);
});
});
Pour obtenir les meilleurs résultats avec page.evaluate
, vous devez vous concentrer sur l'amélioration des performances, la réduction des changements de contexte inutiles et la sécurité. Voici comment affiner les workflows d'automatisation de votre navigateur.
Exécuter efficacement du code dans le contexte de la page permet de gagner du temps et d'économiser des ressources système. Voici quelques techniques pour accélérer vos scripts :
// Block unnecessary resources like images and stylesheets
await page.setRequestInterception(true);
page.on('request', request => {
if (['image', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
// Batch operations to reduce overhead
await page.evaluate(() => {
const results = [];
document.querySelectorAll('.product-item').forEach(item => {
results.push({
title: item.querySelector('.title').textContent,
price: item.querySelector('.price').textContent,
stock: item.querySelector('.stock').dataset.value
});
});
return results;
});
Le choix des bons sélecteurs joue également un rôle important dans la performance :
Type de sélecteur | Vitesse | Exemple |
---|---|---|
ID | Résultats des tests | #main-content |
Classe | Rapide | .product-item |
Jour | Modérée | div > span |
XPath complexe | Le plus lent | //div[@class='wrapper']//span |
Le changement de contexte entre Node.js et l'environnement du navigateur peut ralentir l'exécution. Voici comment le minimiser :
// Example of inefficient context switching
for (const item of items) {
await page.evaluate((i) => {
document.querySelector(`#item-${i}`).click();
}, item);
}
// Better: Batch operations in a single context switch
await page.evaluate((itemsList) => {
itemsList.forEach(i => {
document.querySelector(`#item-${i}`).click();
});
}, items);
Si vous devez traiter des données dans Node.js et les renvoyer au navigateur, exposez des fonctions au lieu de changer de contexte à plusieurs reprises :
await page.exposeFunction('processData', async (data) => {
// Process data in Node.js
return transformedData;
});
await page.evaluate(async () => {
const result = await window.processData(documentData);
// Use the processed data in the browser
});
Une fois les performances et le changement de contexte optimisés, concentrez-vous sur la sécurité de vos scripts. Voici quelques bonnes pratiques :
// Always sanitize inputs before using them
const sanitizedInput = sanitizeHtml(userInput);
await page.evaluate((input) => {
document.querySelector('#search').value = input;
}, sanitizedInput);
// Use error handling for critical operations
try {
await page.evaluate(() => {
if (!window.__securityCheck) {
throw new Error('Security check failed');
}
// Continue with the operation
});
} catch (error) {
console.error('Security violation:', error);
}
Pour les workflows Latenode, tenez compte de ces conseils supplémentaires :
userDataDir
pour mettre en cache les ressources et améliorer les performances entre les sessions.Le page.evaluate
La méthode connecte Node.js et les contextes du navigateur en envoyant une fonction JavaScript transformée en chaîne à exécuter dans le navigateur. Cette fonction fonctionne indépendamment de l'environnement Node.js ; le transfert de données doit donc être géré avec précaution.
Voici un exemple courant d’extraction de données :
const data = await page.evaluate(async () => {
const results = document.querySelectorAll('.data-item');
return Array.from(results, item => ({
id: item.dataset.id,
value: item.textContent.trim()
}));
});
Les choses à garder à l'esprit:
evaluate
contexteCes bases constituent les bases d'une utilisation efficace de Puppeteer. Des outils supplémentaires peuvent encore optimiser vos tâches d'automatisation.
Puppeteer propose plusieurs outils pour étendre les capacités de page.evaluate
:
Outil | Objectif | Meilleur cas d'utilisation |
---|---|---|
page.evaluateHandle |
Renvoie les références d'objet | Interagir directement avec les éléments DOM |
page.exposeFunction |
Rend les fonctions Node.js utilisables dans le navigateur | Gestion d'une logique complexe côté serveur |
page.evaluateOnNewDocument |
Exécute des scripts avant le chargement d'une page | Préparation préalable de l'environnement du navigateur |
Par exemple, l'exposition des fonctions Node.js au navigateur peut simplifier le traitement avancé des données dans les workflows comme ceux de Latenode. page.evaluate
fonctionne bien pour gérer les types primitifs et les objets sérialisables JSON, page.evaluateHandle
est essentiel pour traiter des objets de navigateur complexes qui ne peuvent pas être sérialisés.