Ideas básicas
Origin:master: Starting from a certain category of Wikipedia (such as aircraft carrier (key) page, find out all targets containing key (aircraft carrier) in the title attribute of the link, and add them to the queue to be crawled. In this way, while grabbing the code and pictures of a page, it also obtains the addresses of all other web pages related to the key on the web page, and adopts an algorithm that prioritizes transversal de la amplitud de clase para completar esta tarea.
Idea 2 (Origen: CAT): Grawl por clasificación. Tenga en cuenta que en Wikipedia, las categorías comienzan con la categoría:. Dado que Wikipedia tiene una buena estructura de documentos, es fácil comenzar con cualquier categoría y siempre rastrear todas las categorías debajo de ella. Este algoritmo extrae subcategorizaciones para páginas de clasificación y toma todas las páginas debajo de ella en paralelo. Es rápido y puede guardar la estructura de clasificación, pero de hecho hay muchas páginas duplicadas, pero esto se puede procesar fácilmente escribiendo un script en la etapa posterior.
Selección de biblioteca
Empecé a querer usar JSDOM. Aunque sentí que era poderoso, también era bastante "pesado". Lo más serio era que el documento de explicación no era lo suficientemente bueno. Solo mencioné sus ventajas, pero no tenía una explicación integral. Por lo tanto, si cambia a Cheerio, es liviano y tiene funciones relativamente completas. Al menos puedes tener un concepto integral de un vistazo. De hecho, después de hacerlo, me di cuenta de que no hay necesidad de bibliotecas, ¡y puede hacer todo con expresiones regulares! Acabo de escribir un poco de regularidad en la biblioteca.
Puntos clave
Configuración de variables globales:
var regkey = ['portador de aeronaves', 'portador de aeronaves', 'portador de aeronaves']; // Si las palabras clave están incluidas en el enlace, es el objetivo var allkeys = []; // El título del enlace también es el identificador de la página, evitando el rastreo repetido de las claves VAR = ['Categoría:%E8%88%AA%E7%A9%BA%E6%AF%8D%E8%88%B0']; // esperando cola, página de inicio
Descarga de imágenes
Use la operación de transmisión de la biblioteca de solicitudes para que cada operación de descarga sea un cierre. Presta atención a los posibles efectos secundarios de las operaciones asincrónicas. Además, el nombre de la imagen debe restablecerse. Al principio, tomé el nombre original. Por algunas razones, algunas imágenes claramente existen, pero no se pueden mostrar; y el atributo SRCSET debe limpiarse, de lo contrario, la superficie original no se puede mostrar.
$ = Cheer.load (Downhtml); var rshtml = $ .html (); var imgs = $ ('#bodyContent .image'); // Las imágenes están modificadas por este estilo para (img en imgs) {if (typeof imgs [img] .attribs === 'indefinido' || typeof imgs [img] .Attribs.href === 'UNDEFINADO') {continúa;} // La estructura es una imagen bajo el enlace, y el enlace no existe, skip {var Picurl = IMGS [img] .Children [0] .Attribs.src; // La dirección de imagen var dirs = picurl.split ('.'); var filename = baseIR+uuid.v1 ()+'.'+dirs [dir.length -1]; // Cambiar el nombre de solicitud ("https:"+picurl) .pipe (fs.CreateWriteStream ('Pages/'+FileName)); // descargar rshtml = rshtml.replace (picurl, nombre de archivo); // reemplazar la ruta local // console.log (picurl); }}Atravesante de la prioridad
Al principio, no entendí completamente el concepto de asíncrona y lo hice en un bucle. Pensé que usar Promise ya se había convertido en sincronización, pero de hecho, solo asegura que las operaciones entregadas a Promise se llevarán a cabo de manera ordenada, ¡y estas operaciones no se pueden ordenar con otras operaciones! Por ejemplo, el siguiente código es incorrecto.
var teclas = ['Aircraft portador']; var key = keys.shift (); while (key) {data.get ({url: encodeuri (key), qs: null}). entonces (function (downhtml) {... keys.push (key); // (1)}}); key = keys.hift (); // (2)}¡La operación anterior es normal, pero de hecho (2) se ejecutará entre (1)! ¿Qué hacer?
Usé la recursión para resolver este problema. El siguiente código de ejemplo:
var key = keys.shift (); (function doSext (key) {data.get ({url: key, qs: null}). entonces (function (downhtml) {... keys.push (href); ... key = keys. keys.); if (key) {dudext (key);} else {console.log ('la tarea de crawl se completó suavemente. })})(llave);Limpieza regular
Use expresiones regulares para limpiar el código de página inútil, porque hay muchos patrones para procesarse, por lo que escribí un bucle para procesarlo de manera uniforme.
var regs = [/<link rel =/"stylesheet/" href =/"? [^/"]*/">/g,/<script>? [^<]*<// script>/g,/<style>? [^<]*<// style>/g,/<a? [^>]*>/g,/</a>/g,/srcset = ((((^/"/"] regs.forEach (function (rs) {var mactches = rshtml.match (rs); for (var i = 0; i <mactches.length; i ++) {rshtml = rshtml.replace (mactches [i], mactches [i] .indexof ('stylesheet')>-1? href = "wiki '+(i+1)+'. css" ':' ');Efecto de ejecución
Necesito FQ en Wiki chino. Lo probé y agarré la clasificación del portaaviones. Durante la operación, encontré alrededor de 300 enlaces relacionados (incluidas las páginas de clasificación. Solo tomé enlaces válidos y no los descargué). Finalmente, descargué 209 correctamente. Probé manualmente algunos enlaces de error y descubrí que eran enlaces no válidos. Mostró que la entrada aún no se había establecido. Todo el proceso tomó aproximadamente menos de quince minutos. Después de la compresión, era de casi treinta m y sintió que el efecto era bastante bueno.
código fuente
https://github.com/zhoutk/wikispider
resumen
Para cuando básicamente había completado la tarea anoche, la Idea 1 puede rastrear páginas con contenido relativamente preciso, y las páginas no se repiten, pero la eficiencia de rastreo no es alta, y la información clasificada no puede obtenerse con precisión; La Idea 2 puede rastrear y almacenar automáticamente archivos localmente en categorías de acuerdo con Wikipedia, que es altamente eficiente (medición real, rastreo [buque de guerra] y rastreo de casi 6,000 páginas en total, que toma aproximadamente 50 minutos, y más de 100 páginas se pueden rastrear por minuto), y puede ahorrar con precisión información clasificada.
La mayor ganancia es una comprensión profunda del control general del proceso de la programación asincrónica.