Aujourd'hui, le compromis Web est une technologie bien connue, mais il existe encore de nombreuses complexités. Les robots Web simples sont toujours difficiles à concurrencer avec les sites Web modernes développés par diverses technologies complexes telles que la formation AJAX, XMLHTTPRequest, WebSockets, Flash Sockets, etc.
Prenons l'exemple de nos besoins de base sur le projet Hubdoc, dans lequel nous comptons le montant de la facture, la date d'expiration, le numéro de compte et, surtout: les PDF des factures récentes des sites Web des banques, des services publics et des sociétés de cartes de crédit. Pour ce projet, j'ai commencé avec une solution très simple (n'utilisant pas le produit commercial coûteux que nous évaluons pour le moment) - un projet de robot simple que je faisais avec Perl dans Messagelab / Symantec. Mais les résultats n'allaient pas bien, et les spammeurs ont fait un site Web beaucoup plus simple que ceux des banques et des services publics.
Alors, comment résoudre ce problème? Nous commençons principalement par l'excellente bibliothèque de demandes développée à l'aide de Mikea. Faites une demande dans le navigateur et vérifiez quelles en-têtes de demande ont été envoyées dans la fenêtre du réseau, puis copiez ces en-têtes de demande dans le code. Ce processus est très simple. Il s'agit simplement de suivre toutes les demandes de la connexion au téléchargement du fichier PDF, puis de simuler toutes les demandes de ce processus. Afin de faciliter la gestion des choses similaires et de rendre les développeurs Web plus rationnels dans l'écriture de programmes de robottes, j'ai exporté les résultats de HTML à JQuery (en utilisant la bibliothèque Cheato légère), ce qui rend le travail similaire simple et facilite l'utilisation du sélecteur CSS pour sélectionner des éléments dans une page. L'ensemble du processus est enveloppé dans un cadre, qui peut également effectuer des travaux supplémentaires, tels que la prise en charge des certificats de la base de données, le chargement des robots individuels et la communication avec l'interface utilisateur via socket.io.
Cela fonctionne pour certains sites Web, mais c'est juste un script JS, pas mon code Node.js qui est placé sur leur site par ces sociétés. Ils peuvent superposer les problèmes restants pour répondre à la complexité, ce qui vous rend très difficile de comprendre quoi faire pour obtenir le point d'information de connexion. Pour certains sites, j'ai essayé de l'obtenir en le combinant avec la bibliothèque demandes () pendant quelques jours, mais c'était toujours en vain.
Après presque s'écraser, j'ai découvert Node-PhantoMJS, une bibliothèque qui me permet de contrôler le navigateur Webkit sans tête Phantomjs à partir du nœud (Note du traducteur: Je ne m'attendais pas à un nom correspondant. Cela semble être une solution simple, mais il y a des problèmes que les Phantomjs ne peuvent pas éviter:
1. PhantoMJS ne peut que vous dire si la page a été chargée, mais vous ne pouvez pas déterminer s'il existe une redirection (redirection) implémentée via des balises JavaScript ou Meta dans ce processus. Surtout lorsque JavaScript utilise SetTimeout () pour retarder les appels.
2.PhantoMJS vous fournit un crochet à la mise en page qui vous permet de faire face aux problèmes mentionnés ci-dessus, mais cette fonction ne peut réduire ce nombre que lorsque vous déterminez le nombre de pages à charger, réduisez ce nombre lorsque chaque page est chargée et fournissez un traitement possible (car cela ne se produit pas toujours), de sorte que lorsque votre nombre est réduit à 0, votre fonction de rappel peut être appelée. Cette méthode peut fonctionner, mais cela fait toujours se sentir un peu comme un pirate.
3. Phantomjs nécessite un processus complet et indépendant pour que chaque page rampe, car si ce n'est pas le cas, il est impossible de séparer les cookies entre chaque page. Si vous utilisez le même processus Phantomjs, la session de la page qui a été connectée sera envoyée à une autre page.
4. Impossible d'utiliser des Phantomjs pour télécharger des ressources - vous ne pouvez enregistrer la page que en PNG ou PDF. Ceci est utile, mais cela signifie que nous devons recourir pour demander () pour télécharger le PDF.
5. Pour les raisons ci-dessus, je dois trouver un moyen de distribuer des cookies de la session Phantomjs à la bibliothèque de session de request (). Distribuez simplement la chaîne Document.cookie, analysez-la et injectez-la dans le pot de cookie de request ().
6. Injection de variables dans la session du navigateur n'est pas facile. Pour ce faire, je dois créer une chaîne pour créer une fonction JavaScript.
La copie de code est la suivante:
Robot.prototype.add_page_data = fonction (page, nom, données) {
page.evaluate (
"function () {var" + name + "= fenêtre." + nom + "=" + json.stringify (data) + "}"
));
}
7. Certains sites Web sont toujours remplis de code comme Console.log (), et ils doivent être redéfinis et sortir à l'emplacement que nous voulons. Pour ce faire, j'ai fait ceci:
La copie de code est la suivante:
if (! Console.log) {
var iframe = document.createElement ("iframe");
document.body.appendChild (iframe);
console = window.frames [0] .Console;
}
8. Certains sites Web sont toujours remplis de code comme console.log (), et ils doivent être redéfinis et sortir à l'emplacement que nous voulons. Pour ce faire, j'ai fait ceci:
La copie de code est la suivante:
if (! Console.log) {
var iframe = document.createElement ("iframe");
document.body.appendChild (iframe);
console = window.frames [0] .Console;
}
9. Il n'est pas facile de dire au navigateur que j'ai cliqué sur la balise A. Pour accomplir ces choses, j'ai ajouté le code suivant:
La copie de code est la suivante:
var clickelement = window.clickElement = function (id) {
var a = document.getElementById (id);
var e = document.CreateEvent ("MouseEvents");
e.InitMousEEvent ("Click", true, true, fenêtre, 0, 0, 0, 0, false, false, false, false, 0, null);
A.DispatchEvent (E);
};
10. Je dois également limiter la concurrence maximale de la session du navigateur pour nous assurer que nous n'exploserons pas le serveur. Même ainsi, cette limitation est beaucoup plus élevée que ce que les solutions commerciales coûteuses peuvent offrir. (Note du traducteur: c'est-à-dire que la concurrence d'une solution commerciale est supérieure à celle de cette solution)
Après tout le travail, j'ai une solution de robot relativement décente pour la demande PhantoMJS +. Vous devez vous connecter avec PhantoMJS avant de pouvoir revenir à la demande de demande (). Il utilisera des cookies définis dans PhantoMJS pour vérifier la session connectée. Il s'agit d'une énorme victoire car nous pouvons utiliser le flux de request () pour télécharger le fichier PDF.
L'ensemble du plan est de rendre relativement facile pour les développeurs Web de comprendre comment utiliser les sélecteurs JQuery et CSS pour créer des robots pour différents sites Web. Je n'ai pas réussi à prouver que cette idée est réalisable, mais je crois qu'elle se produira bientôt.