GOW

GOW

segunda-feira, 1 de junho de 2026

Criando um Web Crawler com jsoup

 O Crawler é um software que faz uma varredura sistemática e mais ou menos ampla na Internet em busca de informações relevantes como textos, endereços de e-mail e links que são utilizados para encontrar outras páginas iterativamente de acordo com regras bem definidas. O processo realizar pelo crawler é chamado de crawling.

Também conhecido como Spider ou Bot, esse software é a base dos motores de busca devido à sua capacidade de indexar sites. Para facilitar o trabalho dos crawlers e tornar a indexação das páginas mais rápida, o site deve possuir alguns artefatos:

sitemap.xml: lista das páginas do site, que pode ser utilizada para que o crawler saiba de antemão que páginas existem para indexar;

robots.txt: regras de acesso que impedem o crawler de indexar certas páginas;

tag meta robots: através do valores “noindex” ou “nofollow”, a página avisa ao crawler que ele não deve, respectivamente, indexá-la e nem seguir os links contidos nela;

rel=”nofollow”: indica ao crawler que aquele link não deve ser seguido.

Um Crawler deve respeitar as regras impostas pelo site visitado, deve evitar visitar as páginas com muita frequência e também deve ser robusto para evitar spider traps e outros comportamento maliciosos. Outros bons atributos de um crawler são a distribuição em máquinas diferentes, escalabilidade, continuidade e priorização baseada na qualidade da página.

Os motores de busca em particular utilizam os crawlers para baixar o conteúdo das páginas de Internet e possibilitar um pós processamento, o que diminui o tempo de resposta para busca daquelas páginas. Crawlers também podem ser utilizados validar o HTML e para verificar se não há links quebrados na página em processo automatizado.

Um Crawler segue o seguinte processo:

1. Obter uma URL da fronteira (esse conceito será explicado na próxima seção)
2. Baixar o código HTML
3. Parsear o HTML para extrair links e outras URLs
4. Verificar se a URL e/ou o conteúdo já foi analisado anteriormente. Se não foi, indexar.
5. Confirmar, para cada URL extraída, se ela permite ser verificada com relação à frequência, às regras do robots.txt e outras restrições

Fronteira

Um conceito fundamental dos crawlers é a fronteira. A fronteira define o comportamento do crawler ao visitar uma página, como prioridade, ordem, profundidade, etc.

A fronteira deve ser inicializada com URLs que serão denominadas seeds (sementes). Para cada página visitada, o crawler perguntará para a fronteira que páginas devem ser visitadas à seguir. A fronteira é informada de todo o conteúdo baixado pelo crawler de forma contínua até que a condição de parada seja atingida. Como a fronteira é uma camada de abstração, sua implementação pode ter várias tipos diferentes de persistência de acordo com a necessidade do negócio.

Exemplo com jsoup

O jsoup é uma biblioteca que fornece uma API para baixar, extrair e manipular dados da Internet. Adicione a dependência abaixo ao seu projeto:

1
2
3
4
5
<dependency>
   <groupId>org.jsoup</groupId>
   <artifactId>jsoup</artifactId>
    <version>1.10.2</version>
</dependency>

Vamos fazer um exemplo simples que baixa o conteúdo de uma página e exibe no console o título de todas as URLs encontradas na página:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
 
public class BasicWebCrawler {
   private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) "
    + "AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1";
   private HashSet<String> links;
   private List<Article> articles;
   private List<String> frontiers;
     
   class Article{
      String title;
      String url;
      public Article(String title, String url) {
         this.title = title;
         this.url = url;
      }
   }
     
   public BasicWebCrawler() {
      links = new HashSet<>();
      articles = new ArrayList<>();
      frontiers = new ArrayList<>();
   }
 
   public void addFrontier(String fronteira) {
      frontiers.add(fronteira);
   }
     
   public void crowl(int depth) {
      frontiers.forEach(url -> {
         crowlPageLinks(url, depth);
      });
      crowlArticles();
   }
     
   private void crowlPageLinks(String url, int depth) {
      if ((!links.contains(url) && (0 < depth) && !url.trim().isEmpty())) {
         try {
            links.add(url);
            Document document = Jsoup.connect(url).userAgent(USER_AGENT).get();
            Elements linksOnPage = document.select("a[href]");
            for (Element page : linksOnPage) {
               crowlPageLinks(page.attr("abs:href"), --depth);
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }
 
   private void crowlArticles() {
      links.forEach(url -> {
         Document document;
         try {
            document = Jsoup.connect(url).userAgent(USER_AGENT).get();
            Elements elementLinks = document.select("a[href]");
            for (Element element : elementLinks) {
               Article article = new Article(element.text(), element.attr("abs:href"));
               articles.add(article);
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
      });
   }
 
   public void print() {
      articles.forEach(a -> {
         System.out.println("> Título: " + a.title);
         System.out.println(">    URL: " + a.url + "\n");
      });
   }
 
   public static void main(String[] args) {
      BasicWebCrawler bwc = new BasicWebCrawler();
      bwc.addFrontier("https://atitudereflexiva.wordpress.com/");
      bwc.crowl(1);
      bwc.print();
   }
}

Adicionei uma fronteira, uma profundidade e tomei alguns cuidados para não visitar a mesma URL mais de uma vez. Como a profundidade está configurada como 1, não estou seguindo os links coletados na primeira página visitada, que no caso é a própria fronteira. Sendo assim, nesse caso, a verificação de página visitada não seria necessária, porém, se você quiser aumentar a profundidade e para permitir que seu crwaling vá mais longe, essa verificação é necessária. Se você quiser aplicar alguma restrição baseada em elementos presentes na página, basta filtrar os elementos do documento baixado. Supondo que a restrição se aplica aos elementos contidos em “p”:

1
String pagina = document.select("p").html();

Note que configuramos o USER_AGENT antes de acionar o crawler. Isso é necessário para nos precavermos da possível confusão que os http servers fazem quando são visitados por crawlers. Forçando o agente, impedimos que o servidor envie uma versão da página formatada para dispositivos móveis.

Sobre a Legalidade do Crawling

O crawling não é uma atividade ilegal, mas isso não significa que você possa baixar o site que quiser. Essa atividade tem uma conotação negativa por causa da forma de acesso e da possibilidade de uso malicioso das informações coletadas:

1. Informações privadas ou importantes
2. Não respeitar os termos de serviço do site
3. Forma abusiva de fazer requisições, o que pode causar problemas nos servidores das paáginas

Muitos sites bloqueiam explicitamente quaisquer tipo de extração automatizada de informações via o arquivo robots.txt. Se o robots.txt estiver assim:

1
2
User-agent: *
Disallow:

Você pode fazer o crawling de todas as páginas do site. Porém, se o robots.txt estiver assim:

1
2
User-agent: *
Disallow: /

Você não poderá fazer o crawling de nenhuma página. Seguem algumas sugestões para um crawling ético:

1. Faça o crawling discretamente, mas antes cheque o arquivo robots.txt
2. Seja conservador evite fazer muitas requisições seguidas às informações para não causar sobrecarga ou negação de serviço (DoS)
3. Use o dado com sabedoria para aumentar o crescimento do seu negócio. Não faça uma cópia do dado que sirva apenas para replicação em outro lugar
4. Entre em contato com o proprietário do site antes de começar o crawling
5. Não repasse as informações coletadas. Se for um dado valioso, mantenha-o seguro.

Nenhum comentário:

Postar um comentário