/ / ¿Cómo escribir un rastreador? - rastreador web

¿Cómo escribir un rastreador? - rastreador web

He tenido pensamientos de tratar de escribir un rastreador simple que pueda rastrear y producir una lista de sus hallazgos para los sitios web y el contenido de nuestra NPO.

¿Alguien tiene alguna idea sobre cómo hacer esto? ¿Dónde apuntas el rastreador para empezar? ¿Cómo reenvía sus hallazgos y sigue arrastrándose? ¿Cómo sabe lo que encuentra, etc, etc.

Respuestas

145 para la respuesta № 1

Estarás reinventando la rueda, para estar seguro. Pero aquí está lo básico:

  • Una lista de direcciones URL no visitadas: siembre esto con una o más páginas de inicio
  • Una lista de las URL visitadas, para que no vayas en círculos
  • Un conjunto de reglas para las URL que no le interesan, por lo que no indexa todo el Internet

Póngalos en un almacenamiento persistente, para que pueda detener e iniciar el rastreador sin perder el estado.

El algoritmo es:

while(list of unvisited URLs is not empty) {
take URL from list
remove it from the unvisited list and add it to the visited list
fetch content
record whatever it is you want to about the content
if content is HTML {
parse out URLs from links
foreach URL {
if it matches your rules
and it"s not already in either the visited or unvisited list
add it to the unvisited list
}
}
}

29 para la respuesta № 2

La parte complicada de un rastreador es si desea escalarla a una gran cantidad de sitios web / solicitudes. En esta situación, tendrá que lidiar con algunos problemas como:

  • Imposibilidad de mantener toda la información en una base de datos.

  • No hay suficiente RAM para tratar con grandes índices

  • Rendimiento multiproceso y concurrencia

  • Trampas del rastreador (bucle infinito creado al cambiar las URL, calendarios, ids de sesiones ...) y contenido duplicado.

  • Rastrear desde más de una computadora

  • Códigos HTML mal formados

  • Constantes errores http de servidores

  • Bases de datos sin compresión, que hacen que su necesidad de espacio sea 8 veces más grande.

  • Rutinas de reenganche y prioridades.

  • Utilice solicitudes con compresión (Deflate / gzip) (bueno para cualquier tipo de rastreador).

Y algunas cosas importantes

  • Respetar robots.txt

  • Y un retraso del rastreador en cada solicitud para no sofocar los servidores web.


8 para la respuesta № 3

Rastreador web multiproceso

Si desea rastrear sitios web de gran tamaño, entoncesdebe escribir un rastreador de múltiples subprocesos. Conectar, obtener y escribir información rastreada en archivos / base de datos: estos son los tres pasos para rastrear, pero si usa un solo hilo, su CPU y la utilización de la red se verán vertidas.

Un rastreador web de múltiples subprocesos necesita dos estructuras de datos: enlaces visitados (esto debe implementarse como un hashmap o trai) y enlaces ToBeVisited (esto es una cola).

El rastreador web utiliza BFS para recorrer la web en todo el mundo.

Algoritmo de un rastreador web básico: -

  1. Agregue una o más URLs de enlaces para enlaces a la visita. El método para agregar una url a linksToBeVisited debe estar sincronizado.
  2. Pop un elemento de linksToBeVisited y agregue esto a linksVisited. Este método emergente para hacer emerger la url desde linksToBeVisited debe estar sincronizado.
  3. Busca la página de internet.
  4. Analice el archivo y agregue cualquier enlace hasta ahora no visitado que se encuentre en la página para linksToBeVisited. Las URL "s pueden filtrarse si es necesario. El usuario puede dar un conjunto de reglas para filtrar qué url" se analizarán.
  5. La información necesaria que se encuentra en la página se guarda en la base de datos o archivo.
  6. repita los pasos 2 a 5 hasta que la cola esté vacía.

    Aquí hay un fragmento de código sobre cómo sincronizar los hilos ....

     public void add(String site) {
    synchronized (this) {
    if (!linksVisited.contains(site)) {
    linksToBeVisited.add(site);
    }
    }
    }
    
    public String next() {
    if (linksToBeVisited.size() == 0) {
    return null;
    }
    synchronized (this) {
    // Need to check again if size has changed
    if (linksToBeVisited.size() > 0) {
    String s = linksToBeVisited.get(0);
    linksToBeVisited.remove(0);
    linksVisited.add(s);
    return s;
    }
    return null;
    }
    }
    


5 para la respuesta № 4

Si los sitios de su NPO son relativamente grandes o complejos (si tiene páginas dinámicas que crearán efectivamente un "agujero negro" como un calendario con un enlace "al día siguiente"), sería mejor usar un rastreador web real, como Heritrix.

Si los sitios suman un número reducido de páginas, puedeSalte con solo usar curl o wget o el tuyo. Solo recuerde si comienzan a crecer o usted comienza a hacer que su secuencia de comandos sea más compleja para usar un rastreador real o al menos mirar su fuente para ver qué están haciendo y por qué.

Algunos problemas (hay más):

  • Agujeros negros (como se describe)
  • Reintentos (¿y si obtienes 500?)
  • Redirecciones
  • Control de flujo (de lo contrario puede ser una carga para los sitios)
  • Implementación de robots.txt

4 para la respuesta № 5

Los rastreadores son simples en concepto.

Obtiene una página raíz a través de HTTP GET, la analiza para encontrar las URL y las pone en una cola a menos que ya hayan sido analizadas (por lo que necesita un registro global de las páginas que ya ha analizado).

Puede usar el encabezado de tipo de contenido para averiguar cuál es el tipo de contenido y limitar su rastreador para que solo analice los tipos de HTML.

Puedes quitar las etiquetas HTML para obtener el planoTexto, en el que puede hacer análisis de texto (para obtener etiquetas, etc., la carne de la página). Incluso podrías hacer eso en las etiquetas alt / title para las imágenes si obtuvieras ese nivel avanzado.

Y en el fondo, puedes tener un grupo de hilos que comen las URL de la cola y hacen lo mismo. Usted quiere limitar el número de hilos por supuesto.


4 para la respuesta № 6

Wikipedia tiene un buen artículo sobre rastreadores web, cubriendo muchos de los algoritmos y consideraciones.

Sin embargo, no me molestaría en escribir mi propio rastreador. Es mucho trabajo, y como solo necesita un "rastreador simple", creo que todo lo que realmente necesita es un rastreador comercial. Hay muchos rastreadores gratuitos y de código abierto que probablemente harán todo lo que necesites, con muy poco trabajo de tu parte.


2 para la respuesta № 7

Puede hacer una lista de palabras y hacer un hilo por cada palabra buscada en google.
Luego, cada hilo creará un nuevo hilo para cada enlace que encuentre en la página.
Cada hilo debe escribir lo que encuentra en una base de datos. Cuando cada hilo termina de leer la página, termina.
Y ahí tienes una gran base de datos de enlaces en tu base de datos.


1 para la respuesta № 8

Estoy usando Open search server para la búsqueda interna de mi empresa, intente esto: http://open-search-server.com También está abierto soruce.


0 para la respuesta № 9

Use wget, haga una descarga web recursiva, que descargará todos los archivos en su disco duro, luego escriba otro script para revisar todos los archivos descargados y analizarlos.

Edit: o tal vez curl en lugar de wget, pero no estoy familiarizado con curl, no sé si hace descargas recursivas como wget.


0 para la respuesta № 10

Hice un rastreador web simple usando una extensión reactiva en .net.

https://github.com/Misterhex/WebCrawler

public class Crawler
{
class ReceivingCrawledUri : ObservableBase<Uri>
{
public int _numberOfLinksLeft = 0;

private ReplaySubject<Uri> _subject = new ReplaySubject<Uri>();
private Uri _rootUri;
private IEnumerable<IUriFilter> _filters;

public ReceivingCrawledUri(Uri uri)
: this(uri, Enumerable.Empty<IUriFilter>().ToArray())
{ }

public ReceivingCrawledUri(Uri uri, params IUriFilter[] filters)
{
_filters = filters;

CrawlAsync(uri).Start();
}

protected override IDisposable SubscribeCore(IObserver<Uri> observer)
{
return _subject.Subscribe(observer);
}

private async Task CrawlAsync(Uri uri)
{
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromMinutes(1) })
{
IEnumerable<Uri> result = new List<Uri>();

try
{
string html = await client.GetStringAsync(uri);
result = CQ.Create(html)["a"].Select(i => i.Attributes["href"]).SafeSelect(i => new Uri(i));
result = Filter(result, _filters.ToArray());

result.ToList().ForEach(async i =>
{
Interlocked.Increment(ref _numberOfLinksLeft);
_subject.OnNext(i);
await CrawlAsync(i);
});
}
catch
{ }

if (Interlocked.Decrement(ref _numberOfLinksLeft) == 0)
_subject.OnCompleted();
}
}

private static List<Uri> Filter(IEnumerable<Uri> uris, params IUriFilter[] filters)
{
var filtered = uris.ToList();
foreach (var filter in filters.ToList())
{
filtered = filter.Filter(filtered);
}
return filtered;
}
}

public IObservable<Uri> Crawl(Uri uri)
{
return new ReceivingCrawledUri(uri, new ExcludeRootUriFilter(uri), new ExternalUriFilter(uri), new AlreadyVisitedUriFilter());
}

public IObservable<Uri> Crawl(Uri uri, params IUriFilter[] filters)
{
return new ReceivingCrawledUri(uri, filters);
}
}

y puedes usarlo de la siguiente manera:

Crawler crawler = new Crawler();
IObservable observable = crawler.Crawl(new Uri("http://www.codinghorror.com/"));
observable.Subscribe(onNext: Console.WriteLine,
onCompleted: () => Console.WriteLine("Crawling completed"));