Red de conocimiento informático - Material del sitio web - Cómo usar Python para crear un rastreador

Cómo usar Python para crear un rastreador

1) En primer lugar, es necesario comprender cómo funciona el rastreador.

Imagina que eres una araña y ahora estás conectado a la "web" de Internet. Luego, debe leer todas las páginas web. ¿Qué hacer? No hay problema, puedes comenzar desde algún lugar, por ejemplo, la página de inicio del People's Daily. Esto se llama páginas iniciales, representadas por $.

En la página de inicio del People's Daily, ves varios enlaces que conducen a esa página. Así que felizmente subiste a la página de "noticias nacionales". ¡Genial, ya has navegado por dos páginas (página de inicio y noticias nacionales)! Independientemente de cómo se procese la página rastreada, imagine que copió la página completa en HTML y se la colocó.

De repente descubres que en la página de noticias nacionales hay un enlace a la "página de inicio". Como araña inteligente, debes saber que no tienes que retroceder porque ya la has visto. Por lo tanto, necesitas usar tu cerebro para guardar las direcciones de las páginas que ya has visto. De esta manera, cada vez que ve un nuevo enlace que puede necesitar ser rastreado, primero verifica mentalmente si ya ha visitado la dirección de esta página. Si has estado allí, no vayas.

Bien, en teoría, si se puede acceder a todas las páginas desde la página inicial, entonces se puede demostrar que definitivamente se pueden rastrear todas las páginas web.

Entonces, ¿cómo implementarlo en Python?

Muy simple

importar cola

initial_page = "Página de inicialización"

url_queue = Queue.Queue()

visto = set()

visto.insert(initial_page)

url_queue.put(initial_page)

while(True): #Continuar hasta el mar desapareció

if url_queue.size()gt;

current_url = url_queue.get() #Obtener la primera URL en la cola

store ( current_url) #Guarde la página web representada por esta URL

para next_url en extract_urls(current_url): #Extraiga la URL vinculada a esta url

si next_url no se ve:

visto.put(next_url)

url_queue.put(next_url)

más:

descanso

Ya está escrito en pseudocódigo.

La columna vertebral de todos los rastreadores está aquí. Analicemos por qué los rastreadores son en realidad algo muy complicado: las empresas de motores de búsqueda suelen tener un equipo completo para mantenerlos y desarrollarlos.

2) Eficiencia

Si procesa directamente el código anterior y lo ejecuta directamente, le llevará un año entero rastrear todo el contenido de Douban. Sin mencionar que los motores de búsqueda como Google necesitan rastrear toda la web.

¿Cuál es el problema? Hay demasiadas páginas web que deben rastrearse y el código anterior es demasiado lento. Supongamos que hay N sitios web en toda la red y luego analice la complejidad del juicio de reutilización como N * log (N), porque todas las páginas web deben atravesarse una vez y reutilizar el conjunto cada vez requiere una complejidad de registro (N).

Está bien, está bien, sé que la implementación establecida de Python es hash, pero esto sigue siendo demasiado lento, al menos el uso de la memoria no es eficiente.

¿Cuál es la práctica habitual de valoración del peso? Bloom Filter. En pocas palabras, sigue siendo un método hash, pero su característica es que puede usar memoria fija (no crece con la cantidad de URL) para determinar si la URL ya está en el conjunto con eficiencia O (1). Desafortunadamente, no hay almuerzo gratis. El único problema es que si la URL no está en el conjunto, BF puede estar 100% seguro de que la URL no ha sido vista. Pero si esta URL está en el conjunto, te dirá: esta URL debería haber aparecido antes, pero tengo 2 dudas. Tenga en cuenta que la incertidumbre aquí puede volverse muy pequeña cuando la memoria que asigna es lo suficientemente grande. Un tutorial simple: Filtros Bloom por ejemplo

Observa esta función Si se ha visto la URL, es posible que se vea repetidamente con una pequeña probabilidad (no importa, no te agotarás si lo haces). verlo más). Pero si no se ha visto, definitivamente se verá (esto es muy importante, de lo contrario nos perderemos algunas páginas web). [IMPORTANTE: Hay un problema con este párrafo, sáltelo por ahora]

Bien, ahora estamos cerca de la forma más rápida de lidiar con el juicio de peso. Otro cuello de botella: sólo tienes una máquina. No importa cuán grande sea su ancho de banda, siempre que la velocidad de su máquina al descargar páginas web sea el cuello de botella, solo podrá acelerar esta velocidad. Si una máquina no es suficiente, ¡use muchas! Por supuesto, asumimos que cada máquina ha alcanzado la máxima eficiencia: utilizando subprocesos múltiples (para Python, multiproceso).

3) Rastreo de clústeres

Al rastrear Douban, utilicé más de 100 máquinas funcionando las 24 horas del día durante un mes. Imagínese si solo usa una máquina, tendrá que ejecutarla durante 100 meses...

Entonces, suponiendo que tenga 100 máquinas disponibles ahora, ¿cómo usar Python para implementar un algoritmo de rastreo distribuido?

A 99 de estas 100 máquinas con menor potencia informática las llamamos esclavas, y la otra máquina más grande se llama maestra. Luego, mirando hacia atrás en url_queue en el código anterior, si podemos poner esta cola en esta cola maestra. máquina, todos los esclavos pueden comunicarse con el maestro a través de la red. Cada vez que un esclavo completa la descarga de una página web, solicita una nueva página web al maestro para rastrear. Cada vez que el esclavo captura una nueva página web, envía todos los enlaces de esta página web a la cola del maestro. De manera similar, el filtro de floración también se coloca en el maestro, pero ahora el maestro solo envía las URL que se determina que no han sido visitadas al esclavo. El filtro Bloom se coloca en la memoria del maestro y la URL visitada se coloca en Redis ejecutándose en el maestro, lo que garantiza que todas las operaciones sean O (1). (Al menos la amortización es O(1). Para conocer la eficiencia del acceso de Redis, consulte: LINSERT – Redis)

Considere cómo implementarlo en Python:

Instale scrapy en cada esclavo, luego cada La máquina se convierte en esclava con capacidades de rastreo, y Redis y rq se instalan en el maestro para usarlos como una cola distribuida.

Luego se escribe el código

#slave.py

current_url = request_from_master()

to_send = []

para next_url en extract_urls(current_url):

to_send.append(next_url)

store(current_url);

send_to_master(to_send)

#master.py

distributed_queue = DistributedQueue()

bf = BloomFilter()

initial_pages = "www.renmingribao.com"

mientras(Verdadero):

si solicitud == 'GET':

si distribuido_queue.size()gt 0:

enviar; (distributed_queue .get())

else:

break

solicitud elif == 'POST':

bf.put( request.url)

Vale, de hecho, como puedes imaginar, alguien ya ha escrito lo que necesitas: darkrho/scrapy-redis · GitHub

4) Outlook y posprocesamiento.

p>

Aunque anteriormente se utilizan muchas palabras "simples", no es fácil implementar un rastreador a escala comercial. El código anterior se puede utilizar para rastrear un sitio web completo sin muchos problemas.

Pero si necesita un posprocesamiento adicional, como

Almacenamiento efectivo (cómo debe organizarse la base de datos)

Juicio efectivo (aquí se refiere a la página web juicio) Pesado, no queremos rastrear tanto el People's Daily como el Damin Daily, que lo plagiaron)

Extracción efectiva de información (por ejemplo, cómo extraer todas las direcciones en la página web, "Distrito de Chaoyang Endeavour Road Zhonghua "Tao"), los motores de búsqueda generalmente no necesitan almacenar toda la información, como por qué guardo imágenes...

Actualización a tiempo (predice con qué frecuencia se actualizará esta página web )

Por ejemplo. Como puedes imaginar, cada punto aquí puede ser estudiado por muchos investigadores durante más de diez años. Aun así,

"El camino es largo y largo, y buscaré de arriba a abajo".

Así que no preguntes cómo empezar, simplemente ponte en marcha :)