Je viens de commencer à utiliser Puppeteer. Essayer d'analyser une page mais la méthode d'évaluation ne fonctionnera pas.
Browser Created Creating Blank Page Page Created Visiting URL Website Loaded undefined Done! Exiting
Résultat:
var Browser var Page var Result puppeteer.launch() .then(function (browser) { console.log('Browser Created\nCreating Blank Page') Browser = browser return Browser.newPage() }) .then(function (page) { console.log('Page Created\nVisiting URL') Page = page return Page.goto(URL) }) .then(function (resp) { console.log('Website Loaded') return Page.evaluate(function () { // Completely Sync Stuff console.log('Evaluating Selectors') var myElems = document.getElementsByClassName('challenge-type light') Result = myElems }) }) .then(function (val) { console.log(Result) console.log('Done! Exiting') Browser.close() process.exit() }) .catch(function (err) { Browser.close() console.log(err) process.exit(1) })
Quelle pourrait être l'erreur? Je préférerais une solution sans async / await.
EDIT: "Evaluating Selectors" n'est pas non plus connecté à la console, donc le code n'y parvient jamais, c'est ma préoccupation.
3 Réponses :
Je revérifierais que
document.getElementsByClassName('challenge-type light')
renvoie un résultat.
Je crois que vous utilisez un navigateur sans tête, donc parfois les éléments peuvent ne pas se charger comme vous vous en doutez .
Je comprends, mais si vous remarquez, "Evaluating Selectors" n'est pas non plus connecté à la console. Il n'exécute jamais ce code.
Les choses fonctionnent enfin.
Cela a fonctionné:
.then(function (resp) { console.log('Website Loaded') return Page.evaluate(function () { return document.querySelector('.cover-heading').innerText }) })
OK, vous êtes sur le bon chemin mais vous avez quelques problèmes.
De votre propre réponse: vous avez noté que les journaux de la console exécutés dans le contexte de la page lorsqu'ils sont exécutés dans le evaluer
méthode. Vous avez raison de dire cela, mais vous avez tort de dire que vous ne pouvez pas retourner d'éléments DOM à partir de la méthode evaluer
. Vous pouvez juste que votre code n'est pas tout à fait correct.
Voici donc ce que vous avez:
.then(function () { return Page.evaluate(function () { // Return the array of elements from inside the evaluate method return document.getElementsByClassName('challenge-type light') }); }) .then(function (elements) { console.log(elements) // Will be your array of elements });
Cela ne fonctionnera pas puisque vous essayez pour affecter myElems
à la variable Result
dans la méthode evaluer
. La méthode evaluer
est exécutée dans le navigateur. Il n'a aucune idée qu'une variable Result
existe dans votre script marionnettiste
. C'est pourquoi votre variable est sortie comme undefined
à la fin.
Pour résoudre ce problème, procédez comme suit:
.then(function (resp) { console.log('Website Loaded') return Page.evaluate(function () { // Completely Sync Stuff console.log('Evaluating Selectors') var myElems = document.getElementsByClassName('challenge-type light') Result = myElems }) }) .then(function (val) { console.log(Result) console.log('Done! Exiting') });
J'espère cela aide!
J'ai fait cela et j'ai obtenu un objet vide pour un sélecteur connu. J'ai essayé exactement ce que vous avez écrit avant d'écrire ma réponse, alors que je ne retournais pas le texte intérieur et que je ne comptais pas sur la prochaine promesse pour le faire, mais tout ce que cela pouvait jamais obtenir était un objet vide. La requête de sélection a renvoyé le type HTMLDivElement qui n'avait aucune signification ailleurs en dehors de l'évaluation, c'est pourquoi j'ai conclu cela. N'hésitez pas à me corriger si je me trompe.
OK si vous obtenez un objet vide, je suggérerais que les noms de classe que vous utilisez dans getElementsByClassName
ne correspondent à aucun élément de l'interface utilisateur. L'autre chose déroutante est que votre question d'origine tente de renvoyer la liste de tous les éléments avec les noms de classe que vous avez spécifiés, mais la réponse que vous avez publiée utilise un nom de classe pas dans votre message d'origine et renvoie également le innerText
qui, encore une fois, est quelque chose de nouveau que vous avez introduit.
êtes-vous sûr que document.getElementsByClassName ('challenge-type light') renvoie réellement un résultat?
N'utilisez pas ces variables globales
Navigateur
,Page
,Résultat
. Il existe de bien meilleures façons d'accéder aux résultats des promesses précédentes dans une chaîne.then ()
!La dernière fois que j'ai vérifié,
page.evaluate
ne prend pas en charge les fermetures. Essayez de ne pas attribuer àRésultat
, à la placerenvoyez
une valeur.... renvoie une valeur sérialisable . Si la fonction passée à
page.evaluate ()
renvoie une valeur non sérialisable, alorspage.evaluate ()
se résout en undefined. Ref