Skip to content

Proyecto opensource que facilita la creación de webscrapper en .NET. Está construido sobre HTMLAgilityPack usando el patrón productor/consumidor, en el cual se puede establecer la cantidad máxima de conexiones simultáneas para no saturar el servidor web.

License

Notifications You must be signed in to change notification settings

vvenegasv/fire-horse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 

Repository files navigation

FireHorse

Proyecto opensource que facilita la creación de webscrapper en .NET. Usando el patrón productor/consumidor, en el cual se puede establecer la cantidad máxima de conexiones simultáneas por dominio para no saturar el servidor web.

1.- Como funciona

Fire Horse es una clase estática, que implementa N ConcurrentQueue por cada dominio al cual se realizarán consultas; y se implementan tantos hilos como dominios existan, los cuales implementan el patrón Productor/Consumidor

2.- Instalación

Este complemento puede ser instalado vía Nuget

Install-Package FireHorse

3.- Requisitos

Requiere contar con framework 4.5.2 o superior

4.- Uso

Primero, se deben definir los métodos o eventos que serán invocados al procesar el elemento. Actualmente se soportan tres eventos: OnDequeue, OnDataArrived y OnExceptio; de los cuales OnDequeue y OnException son opcionales, mientras que OnDataArrived es obligatorio.

4.1- OnDequeue

Es invocado cada vez que un elemento es removido de la cola para ser procesado. Un mismo elemento puede ser removido de la cola varias veces, dado a las políticas de reintento que se implementan en el proceso. La firma es la siguiente:

private void OnDequeue(ScraperDataResponse response)
{
  //Implementar lógica.
}

Se retorna la URL que será leída, así como una lista de clave-valor opcionales, útiles para personalizar el proceso de extracción.

4.2- OnException

Es invocado cuando se produce un error y la política de reintentos establecidas fue superada. Por ejemplo, si se establece una política de tres reintentos, los primeros tres errores no gatillarán este evento; recién el cuarto error será notificado. La firma es la siguiente

private static void OnException(ScraperDataResponse response)
{
  Console.WriteLine(response.Exception);
}

4.3.- OnDataArrived

Invocado cada vez que se retorna satisfactoriamente la información desde el servidor. La firma es la siguiente:

private static void OnDataArrived(ScraperDataResponse response)
{
  switch (response.ScraperType)
  {
      case ScraperType.Binary:
          var data = (byte[]) response.Response;
          break;
      case ScraperType.String:
          var html = (string) response.Response;
          break;
      default:
          throw new Exception("Tipo de scraper inválido");
  }
}

4.4.- Agregar un nuevo elemento a la cola

Para agregar un nuevo elemento a la cola, se debe instanciar un nuevo ScraperData, el cual contiene información de la url que se analizará, así como punteros a los eventos mencionado en los puntos anteriores. Además, contiene un diccionario clave-valor, el cual es útil para agrupar distintos trozos de información que conceptualmente pertenecen a uno solo.

var item = new ScraperData();
item.Url = url;
item.OnDequeue = OnDequeue;
item.OnDataArrived = OnDataArrived;
item.OnThrownException = OnException;
item.ScraperType = ScraperType.String; //o ScraperType.Binary para retornar byte[]
FireHorseManager.Enqueue(item);

4.5.- Esperar a que el proceso concluya

Opcion A: While con sleep Se puede implementar un while con sleep, de la siguiente manera

while (!FireHorseManager.IsEnded && !FireHorseManager.IsActive)
{
    Thread.Sleep(2000);                
}

Opción B: Suscribirse al evento EndProcess Se puede suscribirse al evento FireHorseManager.SubscribeToEndProcess

//Crear un nuevo AutoResetEvent el cual esperará a que se reciba el evento
private static AutoResetEvent _waitHandle = new AutoResetEvent(false);

function getData()
{
  //En algún lugar del código, suscribirse al evento
  var subscriptionKey = FireHorseManager.SubscribeToEndProcess(OnFinish);

  //Do Something...

  //Esperar a que el evento se reciba
  _waitHandle.WaitOne();
}

//Crear método encargado de manejar el evento
private static void OnFinish()
{
    Console.WriteLine("Proceso finalizado.");
    _waitHandle.Set();
}

5.- Configuración

Además, se puede configurar la cantidad máxima de consultas realizadas a un mismo dominio. Por defecto, el valor es 40 y puede ser actualizado de la siguiente manera:

FireHorseManager.MaxRunningElementsByDomain = 5;

6.- Información sobre el proceso

FireHorse implementa algunas propiedades de solo lectura, que permiten conocer el estado del proceso

6.1.- FireHorseManager.CurrentRunningSize

Retorna un entero que informa la cantidad de elementos que están siendo consultados al servidor.

int size = FireHorseManager.CurrentRunningSize;

6.2.- FireHorseManager.CurrentQueueSize

Retorna un entero que informa la cantidad de elementos que existen en todas las colas

int size = FireHorseManager.CurrentQueueSize;

6.3.- FireHorseManager.CurrentRunningSizeByDomain

Retorna un diccionario (Dictionary<string, int>) que contiene por cada dominio, la cantidad de elementos que están siendo consultados al servidor

foreach (var item in FireHorseManager.CurrentRunningSizeByDomain)
{
    Console.WriteLine("Dominio:{0}, Cantidad:{1}", item.Key, item.Value);
}

6.4.- FireHorseManager.CurrentQueues

FireHorse crea un nuevo queue por cada dominio al cual se realizará el proceso de extracción de datos. Estos queue son consumidos con el patrón productor/consumidor en un hilo independiente. Cuando estos queue quedan vacíos, se elimina el queue y el hilo subyacente. Se puede conocer la cantidad de queues con la propiedad CurrentQueues:

Console.WriteLine("Cantidad de colas {0}", FireHorseManager.CurrentQueues);

7.- Detener y Empezar el proceso

Por defecto, el sistema se iniciará de forma automática, y no se detendrá sin importar si hay elementos en la cola o no. Para detener el proceso manualmente, se puede utilizar el método Stop(). La llamada de este método puede tardar un par de segundos en completar, dado que internamente esperará a que los elementos que actualmente están en el estado de "Running", terminen su ejecución.

FireHorseManager.Stop();

Una vez que el proceso ha sido detenido manualmente, sin importar si existen elementos en la cola o no, quedará en ese estado hasta que manualmente sea iniciado con Start().

FireHorseManager.Start();

About

Proyecto opensource que facilita la creación de webscrapper en .NET. Está construido sobre HTMLAgilityPack usando el patrón productor/consumidor, en el cual se puede establecer la cantidad máxima de conexiones simultáneas para no saturar el servidor web.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages