Idées de base
Origine: Master: À partir d'une certaine catégorie de wikipedia (telle que la page de porte-avions (clé), découvrez toutes les cibles contenant la clé (porte-avion) dans l'attribut de titre du lien et les ajoutez à la file d'attente. Traversion de l'étendue de la classe pour terminer cette tâche.
Idée 2 (Origine: Cat): Crawl par classification. Notez que sur Wikipedia, les catégories commencent par la catégorie:. Étant donné que Wikipedia a une bonne structure de documents, il est facile de commencer par n'importe quelle catégorie et de toujours explorer toutes les catégories en dessous. Cet algorithme extrait les sous-catégorisations pour les pages de classification et saisit toutes les pages en dessous en parallèle. Il est rapide et peut enregistrer la structure de classification, mais en fait, il existe de nombreuses pages en double, mais cela peut être facilement traité en écrivant un script au stade ultérieur.
Sélection de la bibliothèque
J'ai commencé à vouloir utiliser JSDom. Bien que je se sente puissant, il était également assez "lourd". La chose la plus sérieuse était que le document d'explication n'était pas assez bon. Je n'ai mentionné que ses avantages, mais je n'ai pas eu d'explication complète. Par conséquent, si vous changez de Cheerio, il est léger et a des fonctions relativement complètes. Au moins, vous pouvez avoir un concept complet en un coup d'œil. En fait, après l'avoir fait, j'ai réalisé qu'il n'y avait pas du tout besoin de bibliothèques, et vous pouvez tout faire avec des expressions régulières! Je viens d'écrire un peu de régularité dans la bibliothèque.
Points clés
Paramètres de variables globales:
var Regkey = ['Aircraft Carrier', 'Aircraft Carrier', 'Aircraft Carrier']; // Si les mots clés sont inclus dans le lien, c'est la cible var allKeys = []; // Le titre du lien est également l'identifiant de la page, évitant la rampe répétée de Var Keys = ['Catégorie:% E8% 88% AA% E7% A9% BA% E6% AF% 8D% E8% 88% B0']; // En attente de file d'attente, page de démarrage
Téléchargement d'image
Utilisez l'opération de streaming de la bibliothèque de requêtes pour faire de la fermeture de chaque formulaire de téléchargement. Faites attention aux effets secondaires possibles des opérations asynchrones. De plus, le nom de l'image doit être réinitialisé. Au début, j'ai pris le nom d'origine. Pour certaines raisons, certaines images existent clairement, mais elles ne peuvent pas être affichées; et l'attribut SRCSET doit être éliminé, sinon la surface d'origine ne peut pas être affichée.
$ = cheer.load (downhtml); var rshtml = $ .html (); var imgs = $ ('# bodyContent .image'); // Les images sont modifiées par ce style pour (img dans imgs) {if (typeof imgs [img] .attribs === 'undefined' || typeof imgs [img] .attribs.href === 'Undefined') {continue;} // la structure est une image sous le lien, et le lien n'existe pas, skip else {var picurl = imgs [img] .children [0] .attribs.src; // l'adresse d'image var dirs = picurl.split ('.'); var filename = basaseir + uuid.v1 () + '.' + dirs [dir.length -1]; // Renommer la demande ("https:" + picurl) .pipe (fs.createwRiteStream ('pages /' + nom de fichier)); // Télécharger rshtml = rshtml.replace (picurl, nom de fichier); // remplacer le chemin local // console.log (picurl); }}Traversion de la priorité de l'étendue
Au début, je ne comprenais pas pleinement le concept de l'asynchrone et je l'ai fait en boucle. Je pensais que l'utilisation de la promesse avait déjà été convertie en synchronisation, mais en fait, elle garantit seulement que les opérations remises à la promesse seront effectuées de manière ordonnée, et ces opérations ne peuvent pas être commandées avec d'autres opérations! Par exemple, le code suivant est incorrect.
var keys = ['Aircraft Carrier']; var key = keys.shift (); while (key) {data.get ({url: encodeuri (key), qs: null}). puis (fonction (downhtml) {... keys.push (key); // (1)}}); key = keys.shift (); // (2)}L'opération ci-dessus est normale, mais en fait (2) sera exécutée entre (1)! Ce qu'il faut faire?
J'ai utilisé la récursivité pour résoudre ce problème. L'exemple de code suivant:
var key = keys.shift (); (fonction DoText (key) {data.get ({url: key, qs: null}). alors (function (dowhtml) {... keys.push (href); ... key = keys.shift (); if (key) {Donex })})(clé);Nettoyage régulier
Utilisez des expressions régulières pour nettoyer le code de page inutile, car il existe de nombreux modèles à traiter, alors j'ai écrit une boucle pour la traiter uniformément.
var regs = [/ <link rel = / "Stylesheet /" href = / "? [^ /"] * / "> / g, / <script>? [^ <] * <// script> / g, / <y style>? [^ <] * <// style> / g, / <a? [^>] *> / g, / </a> / g, / srcset = (/"? [? regs.ForEach (fonction (rs) {var mactches = Shtml.match (rs); pour (var i = 0; i <mactches.length; i ++) {rshtml = rshtml.replace (mactches [i], mactches [i] .Indexof ('Styleheet')> - 1? href = "wiki '+ (i + 1) +'. CSS" ':' ');Effet de course
J'ai besoin de fq sur le chinois wiki. Je l'ai essayé et j'ai attrapé la classification du porte-avions. Pendant l'opération, j'ai trouvé environ 300 liens connexes (y compris les pages de classification. Je n'ai pris que des liens valides et je ne les ai pas téléchargés). Enfin, j'ai téléchargé 209 correctement. J'ai testé manuellement des liens d'erreur et j'ai constaté qu'ils étaient des liens non valides. Il a montré que l'entrée n'avait pas encore été établie. L'ensemble du processus a pris environ moins de quinze minutes. Après la compression, il était près de trente m et il pensait que l'effet était assez bon.
code source
https://github.com/zhoutk/wikispider
résumé
Au moment où j'avais essentiellement terminé la tâche la nuit dernière, l'idée 1 peut ramper avec des pages avec un contenu relativement précise, et les pages ne sont pas répétées, mais l'efficacité rampante n'est pas élevée et les informations classifiées ne peuvent pas être obtenues avec précision; L'idée 2 peut automatiquement ramper et stocker des fichiers localement dans les catégories selon Wikipedia, qui est très efficace (mesure réelle, rampant [navire de guerre] et rampant près de 6 000 pages au total, ce qui prend environ 50 minutes et plus de 100 pages peuvent être rampées par minute), et peuvent économiser avec précision des informations classifiées.
Le plus gros gain est une compréhension approfondie du contrôle global des processus de la programmation asynchrone.