J'utilise CasperJS pour automatiser une série de clics, de formulaires remplis, d'analyses de données, etc. via un site Web.
Casper semble être organisé en une liste d'étapes prédéfinies sous la forme d' then
instructions (voir leur exemple ici: http://casperjs.org/quickstart.html ) mais on ne sait pas ce qui déclenche réellement la prochaine instruction.
Par exemple, then
attend-il que toutes les demandes en attente se terminent? Est-ce que cela injectJS
compte comme une demande en attente? Que se passe-t-il si j'ai une then
instruction imbriquée - enchaînée à la fin d'une open
instruction?
casper.thenOpen('http://example.com/list', function(){
casper.page.injectJs('/libs/jquery.js');
casper.evaluate(function(){
var id = jQuery("span:contains('"+itemName+"')").closest("tr").find("input:first").val();
casper.open("http://example.com/show/"+id); //what if 'then' was added here?
});
});
casper.then(function(){
//parse the 'show' page
});
Je cherche une explication technique du fonctionnement du flux dans CasperJS. Mon problème spécifique est que ma dernière then
déclaration (ci-dessus) s'exécute avant ma casper.open
déclaration et je ne sais pas pourquoi.
la source
flow
de casperjs, mais j'ai découvert que vous ne pouvez pas faire référence à casper à partir d'unevaluate
appel. (c'est-à-dire que vous ne pouvez pas ouvrir une nouvelle URL, un nouveau journal, un écho, etc.). Donc, dans mon cas, evalu a été appelé mais sans moyen d'interagir avec le monde extérieur.evaluate()
est pour le code qui s'exécute dans le "navigateur", dans le DOM de la page que phantomjs parcourt. Donc il n'y en a pascasper.open
, mais il pourrait y avoir jQuery. Votre exemple n'a donc aucun sens, mais je me demande toujours ce quethen()
fait réellement.Réponses:
then()
ajoute essentiellement une nouvelle étape de navigation dans une pile. Une étape est une fonction javascript qui peut faire deux choses différentes:Prenons un scénario de navigation simple:
Vous pouvez imprimer toutes les étapes créées dans la pile comme ceci:
Ça donne:
Notez la
_step()
fonction qui a été ajoutée automatiquement par CasperJS pour charger l'url pour nous; lorsque l'url est chargée, l'étape suivante disponible dans la pile - qui eststep3()
- est appelée.Lorsque vous avez défini vos étapes de navigation, les
run()
exécute une à une de manière séquentielle:Note de bas de page: les éléments de rappel / d'écoute sont une implémentation du modèle Promise .
la source
then()
enregistre simplement une série d'étapes.run()
et sa famille de fonctions de runner, de rappels et d'écouteurs, sont tous ce qui fait réellement le travail d'exécution de chaque étape.Chaque fois une étape est terminée, CasperJS vérifieront contre 3 drapeaux:
pendingWait
,loadInProgress
etnavigationRequested
. Si l'un de ces indicateurs est vrai, ne faites rien, restez inactif jusqu'à une date ultérieure (setInterval
style). Si aucun de ces indicateurs n'est vrai, l'étape suivante sera exécutée.Depuis CasperJS 1.0.0-RC4, une faille existe, où, dans certaines circonstances temporelles, la méthode "essayer de faire l'étape suivante" sera déclenchée avant que CasperJS n'ait le temps de lever l'un des indicateurs
loadInProgress
ounavigationRequested
. La solution est de lever l'un de ces drapeaux avant de quitter toute étape où ces drapeaux devraient être levés (ex: lever un drapeau avant ou après avoir demandé acasper.click()
), peut-être comme ceci:(Remarque: Ceci est seulement illustratif, plus comme psuedocode que le formulaire CasperJS approprié ...)
Pour résumer cette solution en une seule ligne de code, j'ai introduit
blockStep()
dans cette requête d'extraction github , l'extensionclick()
etclickLabel()
comme moyen de garantir que nous obtenons le comportement attendu lors de l'utilisationthen()
. Consultez la demande pour plus d'informations, les modèles d'utilisation et les fichiers de test minimum.la source
blockStep
, à mon humble avisSelon la documentation CasperJS :
then()
Signature:
then(Function then)
Dans les coulisses, le code source de
Casper.prototype.then
est indiqué ci-dessous:Explication:
En d'autres termes,
then()
planifie l'étape suivante du processus de navigation.Lorsqu'elle
then()
est appelée, une fonction lui est transmise en tant que paramètre qui doit être appelée en tant qu'étape.Il vérifie si une instance a démarré, et si ce n'est pas le cas, il affiche l'erreur suivante:
Ensuite, il vérifie si l'
page
objet estnull
.Si la condition est vraie, Casper crée un nouvel
page
objet.Après cela,
then()
valide lestep
paramètre pour vérifier s'il ne s'agit pas d'une fonction.Si le paramètre n'est pas une fonction, il affiche l'erreur suivante:
Ensuite, la fonction vérifie si Casper est en cours d'exécution.
Si Casper n'est pas en cours d'exécution,
then()
ajoute l'étape à la fin de la file d'attente.Sinon, si Casper est en cours d'exécution, il insère une sous-étape d'un niveau plus profond que l'étape précédente.
Enfin, la
then()
fonction se termine en émettant unstep.added
événement et renvoie l'objet Casper.la source