/// <summary> /// Procesa una Uri semilla. Navega por los resultados e inserta nuevas Uris de resultados en la base de datos. /// </summary> /// <param name="seed">La Uri semilla.</param> /// <returns>true si correcto, false si hay algún error</returns> protected bool ProcessSeed(RAI.Crawler.Data.DataUri seed) { Console.WriteLine("Processing Seed " + seed.Id + " : " + seed.AbsoluteUri); Uri uriPaginacion = new Uri(seed.AbsoluteUri); try { // Mientras haya más resultados y no haya error while (uriPaginacion != null) { // Extraer Uris de resultados e insertar en la base de datos // Descargamos el contenido de la Uri semilla String content = Download(uriPaginacion.AbsoluteUri); // Buscamos coincidencias en el contenido descargado con la expresion regular que busca uris de resultados MatchCollection seedUris = GoogleCrawler._resultRegex.Matches(content); // Para cada uri obtenida en el match insertamos un nuevo registro en la base de datos. foreach (Match uri in seedUris) { // Insertamos la uri resultado nueva con el valor de padre inicializado a nuestra semilla RAI.Crawler.Data.DataUri newUri = new Data.DataUri(uri.Groups["uri"].Value.Replace("&", "&"), seed, null, null); // Submit para la base de datos this._context.DataUri.InsertOnSubmit(newUri); } // Extraer siguiente página de resultados Match next = GoogleCrawler._nextRegex.Match(content); // Si encuentra siguiente pagina aumentamos el contador de paginas en 1 y sustituimos uriPaginacion con la nueva if (next.Success) { uriPaginacion = new Uri(uriPaginacion, next.Groups["uri"].Value.Replace("&", "&")); } // Si no uriPaginacion toma valor null else { uriPaginacion = null; // No hay más resultados } } //Si todo es correcto return(true); } catch { } //Si se produce alguna excepcion en el try, error return(false); }
/// <summary> /// Arranca el crawler. No termina hasta que se hayan procesado todas las Uris pendientes. /// </summary> public void Run() { RAI.Crawler.Data.DataUri currentUri = null; while ((currentUri = this.GetPendingUri()) != null) { if (currentUri.IsSeed) { currentUri.Status = this.ProcessSeed(currentUri); } else { currentUri.Status = this.ProcessResult(currentUri); } try { this._context.SubmitChanges(); // Actualizar status en la base de datos } catch (System.Data.SqlClient.SqlException) { } } }
/// <summary> /// Devuelve una Uri pendiente de procesar. /// </summary> /// <returns>La Uri para procesar.</returns> protected RAI.Crawler.Data.DataUri GetPendingUri() { RAI.Crawler.Data.DataUri row = null; row = this._context.DataUri.FirstOrDefault(u => u.Status == null); // default sería null, cuando no hay Uris pendientes return(row); }