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.
