Ir para o conteúdo

Como ignorar URLs não HTML ao rastrear a Web usando C#

Introdução

O rastreamento da Web é o processo de visitar programaticamente páginas da Web e extrair seu conteúdo e links de saída para rastrear recursivamente um site. Ao construir um rastreador da web, é importante buscar e analisar apenas páginas HTML reais, ignorando outros tipos de arquivos, como imagens, vídeos, PDFs, etc. Este artigo explicará dois métodos eficazes para filtrar URLs não HTML em uma web C# rastejante:

  1. Verificando o sufixo do URL em uma lista de extensões de arquivo indesejadas
  2. Executando uma solicitação HEAD leve e inspecionando o cabeçalho de resposta Content-Type

Ao implementar essas técnicas, você pode aumentar a eficiência do seu rastreador e evitar solicitações e processamentos desnecessários. Vamos nos aprofundar nos detalhes de cada método e ver como aplicá-los na prática.

Método 1: verificar sufixos de URL para extensões de arquivo indesejadas

Uma maneira simples de ignorar URLs não HTML é observar a extensão do arquivo no final da string do URL. Você pode manter uma lista de extensões comuns usadas para imagens, arquivos de mídia, documentos e outros ativos que não sejam de páginas da web. Então, antes de buscar um URL, extraia seu sufixo e ignore-o se corresponder a uma dessas extensões.

Aqui está um trecho de código mostrando como filtrar URLs usando esta abordagem em C#:

HashSet<string> UnwantedExtensions = new HashSet<string> { 
  "jpg", "jpeg", "png", "gif", "bmp", "tiff",  // Images
  "mp4", "avi", "mov", "wmv", "flv", "webm",   // Videos 
  "mp3", "wav", "aac", "flac", "ogg",          // Audio
  "pdf", "doc", "docx", "xls", "xlsx", "ppt",  // Documents
  "zip", "tar", "gz", "rar", "7z"              // Archives
}; 

Uri uri = new Uri("http://example.com/image.jpg");
string extension = Path.GetExtension(uri.AbsolutePath).ToLower().TrimStart(‘.‘);

if (UnwantedExtensions.Contains(extension))
{
   Console.WriteLine($"Skipping URL with extension ‘{extension}‘: {uri}");
}
else 
{
   Console.WriteLine($"Fetching URL: {uri}");
   // Crawl the HTML page...
}

Este código define um HashSet de extensões de arquivo indesejadas, então, para um determinado URL, ele extrai a extensão usando Path.GetExtension(). Se a extensão minúscula e aparada por pontos existir no UnwantedExtensions definido, o URL será ignorado. Caso contrário, será buscado e rastreado como uma página HTML.

A grande vantagem deste método é que ele é muito rápido – apenas uma simples operação de string por URL. A desvantagem é que ele depende de URLs com a extensão de arquivo correta, o que nem sempre é o caso. Também é possível ter páginas HTML com .asp or .php extensões que gostaríamos de rastrear, mas que podem ser filtradas.

Método 2: realizar uma solicitação HEAD e inspecionar o cabeçalho do tipo de conteúdo

Uma abordagem mais robusta, mas um pouco mais lenta, é realizar uma solicitação HEAD leve para cada URL e verificar o cabeçalho Content-Type na resposta. Uma solicitação HEAD é semelhante a uma solicitação GET, exceto que solicita ao servidor que retorne apenas os cabeçalhos de resposta e não o conteúdo real.

O cabeçalho Content-Type indica o tipo de mídia do recurso solicitado. Para páginas HTML, o Content-Type normalmente será "text/html". Ao verificar esse valor de cabeçalho, você pode determinar com mais segurança se um URL aponta para uma página HTML ou algum outro tipo de arquivo.

Veja como implementar isso em C#:

HttpClient httpClient = new HttpClient();

Uri uri = new Uri("http://example.com/page");
HttpRequestMessage headRequest = new HttpRequestMessage(HttpMethod.Head, uri);
HttpResponseMessage response = await httpClient.SendAsync(headRequest);

string contentType = response.Content.Headers.ContentType?.MediaType;

if (contentType == "text/html")
{
   Console.WriteLine($"Fetching HTML page: {uri}");
   // Crawl the HTML page...
}  
else
{
   Console.WriteLine($"Skipping non-HTML URL with Content-Type ‘{contentType}‘: {uri}");
}

Isso envia uma solicitação HEAD assíncrona usando HttpClient e recupera o cabeçalho Content-Type da resposta. Se o tipo de mídia for "text/html", o URL será obtido e analisado como uma página HTML. Caso contrário, ele será ignorado e o Content-Type não HTML será registrado.

A vantagem das solicitações HEAD é que elas fornecem uma resposta mais definitiva do tipo de conteúdo direto do servidor. A desvantagem potencial é a latência extra da viagem de ida e volta ao servidor, que pode resultar em um grande número de URLs. No entanto, as solicitações HEAD normalmente são bastante rápidas, pois nenhum conteúdo é retornado.

Combinando os dois métodos para máxima eficácia

Para obter melhor cobertura e eficiência, recomendo usar os dois métodos acima juntos em seu rastreador da web C#. Ao verificar primeiro a extensão de URL em uma lista de bloqueio, você pode filtrar rapidamente URLs não HTML óbvios sem nenhuma solicitação. Então, para URLs que passam por essa verificação, você pode executar uma solicitação HEAD para verificar se é realmente uma página HTML antes de buscá-la completamente.

Esta é a aparência da lógica principal de rastreamento juntando tudo:

public async Task Crawl(Uri uri) 
{
  string extension = Path.GetExtension(uri.AbsolutePath).ToLower().TrimStart(‘.‘);

  if (UnwantedExtensions.Contains(extension))
  {
    Console.WriteLine($"Skipping URL with unwanted extension ‘{extension}‘: {uri}");
    return;
  }

  if (VisitedUrls.Contains(uri))
  {
    Console.WriteLine($"Skipping already visited URL: {uri}");
    return;
  }

  HttpRequestMessage headRequest = new HttpRequestMessage(HttpMethod.Head, uri);
  HttpResponseMessage headResponse = await _httpClient.SendAsync(headRequest);

  string contentType = headResponse.Content.Headers.ContentType?.MediaType;

  if (contentType != "text/html")
  {    
    Console.WriteLine($"Skipping non-HTML URL with Content-Type ‘{contentType}‘: {uri}");
    return;
  }

  VisitedUrls.Add(uri);

  HttpResponseMessage getResponse = await _httpClient.GetAsync(uri);
  string content = await getResponse.Content.ReadAsStringAsync();

  Console.WriteLine($"Crawled URL: {uri}");

  // Parse links from HTML and queue them for crawling
  CrawlQueue.Enqueue(ExtractLinks(uri, content));
}

Esta Crawl O método primeiro verifica a extensão do arquivo da URL e a ignora se estiver no hashset de extensões indesejadas. Em seguida, verifica se o URL já foi visitado e, em caso afirmativo, ignora-o. Em seguida, ele executa uma solicitação HEAD e verifica se o Content-Type é HTML antes de adicionar a URL ao VisitedUrls hashset, buscando totalmente o conteúdo e analisando links para enfileirar para rastreamento adicional.

Usados ​​juntos dessa forma, a filtragem de extensão e as solicitações HEAD fornecem um golpe duplo eficaz para ignorar conteúdo não HTML durante o rastreamento. A verificação de extensão é um filtro preliminar rápido, enquanto a solicitação HEAD é a confirmação final antes de iniciar a busca de página inteira.

Outras considerações e melhores práticas

Além de filtrar URLs não HTML, há outras coisas importantes a serem lembradas ao criar um rastreador da Web eficiente e bem comportado:

  • Sempre respeite as regras do robots.txt e não rastreie páginas não permitidas. Você pode analisar arquivos robots.txt e verificar os URLs deles antes de rastrear.

  • Limite a taxa de rastreamento e o número de solicitações simultâneas para evitar sobrecarregar os servidores. Uma boa diretriz é não mais do que uma solicitação por segundo por domínio.

  • Lide com códigos de status HTTP, tempos limite e erros normalmente. Tente novamente as falhas com espera exponencial e saiba quando desistir.

  • Acompanhe os URLs já visitados usando um hashset, banco de dados ou estrutura de dados eficiente para evitar novo rastreamento de conteúdo duplicado. Um filtro Bloom é uma boa opção que economiza espaço.

Seguindo essas práticas e implementando a filtragem somente HTML, você estará no caminho certo para construir um rastreador da Web educado e focado usando C#. As técnicas explicadas neste artigo devem fornecer tudo o que você precisa para evitar conteúdo irrelevante e aprimorar as páginas HTML de seu interesse.

Conclusão

Os rastreadores da Web são uma ferramenta poderosa para explorar e analisar o conteúdo de sites, mas, para serem eficientes e educados, é fundamental que eles se concentrem nas páginas HTML reais e ignorem outros tipos de URLs. Neste artigo, aprendemos duas técnicas complementares para fazer isso em um rastreador C#:

  1. Filtrando extensões de URL indesejadas
  2. Verificando o cabeçalho Content-Type com uma solicitação HEAD

Examinamos como implementar esses dois métodos e depois vimos como combiná-los para obter uma cobertura mais completa. Também abordamos algumas outras práticas recomendadas do rastreador, como respeitar o robots.txt e limitar a taxa de solicitação.

Esperamos que agora você tenha um conhecimento sólido de como ignorar URLs não HTML com eficiência em seus rastreadores da web. A aplicação dessas técnicas ajudará a manter seu rastreador rápido e focado, evitando carga desnecessária nos servidores.

Aqui estão alguns recursos adicionais que você pode querer verificar para saber mais:

Feliz rastreamento (seletivo)!

Junte-se à conversa

O seu endereço de e-mail não será publicado. Os campos obrigatórios são marcados com *