---
title: "Crawl4AI: Web Scraping com IA em Python"
url: "https://python.dev.br/blog/crawl4ai-web-scraping-ia-python/"
markdown_url: "https://python.dev.br/blog/crawl4ai-web-scraping-ia-python.MD"
description: "Aprenda a usar Crawl4AI para web scraping inteligente com LLMs em Python. Extração estruturada, crawling assíncrono e exemplos."
date: "2026-04-27"
author: "Equipe python.dev.br"
---

# Crawl4AI: Web Scraping com IA em Python

Aprenda a usar Crawl4AI para web scraping inteligente com LLMs em Python. Extração estruturada, crawling assíncrono e exemplos.


Web scraping tradicional exige que você escreva seletores CSS, XPath ou expressões regulares para cada site. Quando a estrutura da página muda, tudo quebra. O **Crawl4AI** propõe uma abordagem diferente: usar **modelos de linguagem (LLMs)** para entender o conteúdo da página e extrair dados de forma inteligente, sem depender da estrutura HTML.

Com mais de 30 mil estrelas no GitHub, o Crawl4AI se tornou a principal biblioteca open-source de web scraping com IA em Python. Neste artigo, vamos ver como instalar, configurar e usar o Crawl4AI para extrair dados estruturados de qualquer página web.

## O que é o Crawl4AI?

O Crawl4AI é uma biblioteca Python que combina **crawling assíncrono** com **extração baseada em LLMs**. Ele usa um navegador headless (Playwright) para renderizar páginas — incluindo conteúdo JavaScript — e depois processa o HTML com estratégias de extração que podem ser baseadas em CSS tradicional ou em modelos de IA.

As principais funcionalidades incluem:

- **Crawling assíncrono** com suporte a múltiplas páginas simultâneas
- **Extração com LLM** usando modelos locais ou APIs como OpenAI e Claude
- **Estratégias de extração** configuráveis (CSS, cosine similarity, LLM)
- **Conversão automática para Markdown** otimizado para LLMs
- **Suporte a JavaScript** via Playwright
- **Cache inteligente** para evitar requisições desnecessárias
- **Chunking** de conteúdo longo para processamento eficiente

## Instalação

A instalação é simples com pip ou [UV](/blog/uv-gerenciador-pacotes-python/):

```bash
# Com pip
pip install crawl4ai
crawl4ai-setup  # Instala o Playwright e navegadores

# Com UV (mais rápido)
uv add crawl4ai
uv run crawl4ai-setup
```

O comando `crawl4ai-setup` baixa o Chromium e configura o Playwright automaticamente.

## Crawling Básico

O uso mais simples do Crawl4AI é extrair o conteúdo de uma página como Markdown:

```python
import asyncio
from crawl4ai import AsyncWebCrawler


async def main():
    async with AsyncWebCrawler() as crawler:
        resultado = await crawler.arun(url="https://python.org")

        print(resultado.markdown[:500])
        print(f"\nLinks encontrados: {len(resultado.links['internal'])}")
        print(f"Imagens: {len(resultado.media['images'])}")


asyncio.run(main())
```

O Crawl4AI retorna um objeto `CrawlResult` com várias representações do conteúdo:

- `resultado.html` — HTML original
- `resultado.markdown` — conteúdo convertido para Markdown
- `resultado.cleaned_html` — HTML limpo sem scripts e estilos
- `resultado.links` — links internos e externos
- `resultado.media` — imagens, vídeos e áudios encontrados

## Extração Estruturada com LLM

O diferencial do Crawl4AI é usar LLMs para extrair dados estruturados. Em vez de escrever seletores CSS, você define um schema [Pydantic](/blog/pydantic-validacao-dados-python/) e deixa o modelo extrair as informações:

```python
import asyncio
from pydantic import BaseModel
from crawl4ai import AsyncWebCrawler
from crawl4ai.extraction_strategy import LLMExtractionStrategy


class Produto(BaseModel):
    nome: str
    preco: float
    descricao: str
    disponivel: bool


async def extrair_produtos(url: str) -> list[Produto]:
    estrategia = LLMExtractionStrategy(
        provider="openai/gpt-4o-mini",
        schema=Produto.model_json_schema(),
        instruction="Extraia todos os produtos da página com nome, preço, descrição e disponibilidade.",
    )

    async with AsyncWebCrawler() as crawler:
        resultado = await crawler.arun(
            url=url,
            extraction_strategy=estrategia,
        )

        return [Produto(**item) for item in resultado.extracted_content]


produtos = asyncio.run(extrair_produtos("https://exemplo.com/produtos"))
for p in produtos:
    print(f"{p.nome}: R$ {p.preco:.2f}")
```

Esse padrão funciona para qualquer tipo de dado: artigos de blog, ofertas de emprego, reviews, catálogos e mais. O LLM entende o contexto da página e extrai os campos mesmo quando a estrutura HTML varia.

## Extração sem LLM: CSS e Cosine Strategy

Nem tudo precisa de IA. O Crawl4AI oferece estratégias de extração que não dependem de LLMs:

### CSS Extraction Strategy

Para sites com estrutura conhecida, a extração por CSS é mais rápida e barata:

```python
import asyncio
from crawl4ai import AsyncWebCrawler
from crawl4ai.extraction_strategy import JsonCssExtractionStrategy

schema = {
    "name": "Artigos",
    "baseSelector": "article.post",
    "fields": [
        {"name": "titulo", "selector": "h2 a", "type": "text"},
        {"name": "link", "selector": "h2 a", "type": "attribute", "attribute": "href"},
        {"name": "resumo", "selector": ".excerpt", "type": "text"},
        {"name": "data", "selector": "time", "type": "attribute", "attribute": "datetime"},
    ],
}


async def main():
    estrategia = JsonCssExtractionStrategy(schema)

    async with AsyncWebCrawler() as crawler:
        resultado = await crawler.arun(
            url="https://blog.exemplo.com",
            extraction_strategy=estrategia,
        )

        for artigo in resultado.extracted_content:
            print(f"- {artigo['titulo']}")


asyncio.run(main())
```

### Cosine Strategy

A estratégia de similaridade por cosseno agrupa conteúdo semanticamente relacionado sem precisar de seletores:

```python
from crawl4ai.extraction_strategy import CosineStrategy

estrategia = CosineStrategy(
    semantic_filter="vagas de emprego python",
    word_count_threshold=50,
    sim_threshold=0.3,
)
```

## Crawling de Múltiplas Páginas

Para projetos que precisam raspar várias páginas, o Crawl4AI oferece crawling assíncrono eficiente:

```python
import asyncio
from crawl4ai import AsyncWebCrawler


async def crawl_multiplas(urls: list[str]):
    async with AsyncWebCrawler() as crawler:
        resultados = await crawler.arun_many(
            urls=urls,
            max_concurrent=5,  # Máximo de páginas simultâneas
        )

        for resultado in resultados:
            if resultado.success:
                print(f"✓ {resultado.url}: {len(resultado.markdown)} chars")
            else:
                print(f"✗ {resultado.url}: {resultado.error_message}")


urls = [
    "https://python.org",
    "https://pypi.org",
    "https://docs.python.org/3/",
]

asyncio.run(crawl_multiplas(urls))
```

## Configurações Avançadas

### Executar JavaScript antes da extração

Páginas com conteúdo dinâmico podem precisar de interações antes da extração:

```python
async with AsyncWebCrawler() as crawler:
    resultado = await crawler.arun(
        url="https://exemplo.com/infinite-scroll",
        js_code=[
            "window.scrollTo(0, document.body.scrollHeight);",
            "await new Promise(r => setTimeout(r, 2000));",
        ],
        wait_for="css:.item:nth-child(20)",  # Esperar 20 itens carregarem
    )
```

### Headers e cookies personalizados

```python
async with AsyncWebCrawler(
    headers={"Accept-Language": "pt-BR,pt;q=0.9"},
    cookies=[{"name": "session", "value": "abc123", "domain": "exemplo.com"}],
) as crawler:
    resultado = await crawler.arun(url="https://exemplo.com")
```

### Cache para desenvolvimento

Durante o desenvolvimento, o cache evita requisições repetidas:

```python
async with AsyncWebCrawler() as crawler:
    # Primeira chamada: faz a requisição
    resultado = await crawler.arun(url="https://exemplo.com", cache_mode="enabled")

    # Segunda chamada: usa o cache
    resultado = await crawler.arun(url="https://exemplo.com", cache_mode="enabled")
```

## Crawl4AI vs BeautifulSoup vs Scrapy

| Recurso | BeautifulSoup | Scrapy | Crawl4AI |
|---------|---------------|--------|----------|
| Extração com LLM | Não | Não | Sim |
| JavaScript rendering | Não | Com plugin | Sim (Playwright) |
| Assíncrono nativo | Não | Sim | Sim |
| Conversão para Markdown | Não | Não | Sim |
| Curva de aprendizado | Baixa | Média | Baixa |
| Ideal para | Parsing simples | Crawling em escala | Extração inteligente |

Para projetos que precisam apenas de parsing HTML simples, [BeautifulSoup com requests](/blog/web-scraping-python/) continua sendo uma boa escolha. Para scraping em larga escala com pipelines complexos, Scrapy é maduro e robusto. O Crawl4AI brilha quando você precisa **extrair dados estruturados de páginas variadas** sem escrever seletores específicos para cada uma.

## Exemplo Completo: Monitorando Vagas de Python

Vamos juntar tudo em um exemplo prático que monitora vagas de emprego:

```python
import asyncio
import json
from datetime import datetime
from pydantic import BaseModel
from crawl4ai import AsyncWebCrawler
from crawl4ai.extraction_strategy import LLMExtractionStrategy


class Vaga(BaseModel):
    titulo: str
    empresa: str
    localizacao: str
    senioridade: str
    salario: str | None = None
    tecnologias: list[str]


async def monitorar_vagas():
    estrategia = LLMExtractionStrategy(
        provider="openai/gpt-4o-mini",
        schema=Vaga.model_json_schema(),
        instruction=(
            "Extraia todas as vagas de emprego relacionadas a Python. "
            "Identifique título, empresa, localização, nível de senioridade, "
            "salário (se disponível) e tecnologias mencionadas."
        ),
    )

    urls = [
        "https://exemplo.com/vagas/python",
        "https://exemplo.com/vagas/backend",
    ]

    async with AsyncWebCrawler() as crawler:
        resultados = await crawler.arun_many(
            urls=urls,
            extraction_strategy=estrategia,
            max_concurrent=3,
        )

        todas_vagas = []
        for resultado in resultados:
            if resultado.success and resultado.extracted_content:
                vagas = [Vaga(**v) for v in resultado.extracted_content]
                todas_vagas.extend(vagas)

        # Salvar resultados
        with open("vagas.json", "w", encoding="utf-8") as f:
            json.dump(
                [v.model_dump() for v in todas_vagas],
                f,
                ensure_ascii=False,
                indent=2,
            )

        print(f"Encontradas {len(todas_vagas)} vagas em {datetime.now():%Y-%m-%d %H:%M}")
        for vaga in todas_vagas[:5]:
            print(f"  - {vaga.titulo} @ {vaga.empresa} ({vaga.senioridade})")


asyncio.run(monitorar_vagas())
```

## Boas Práticas

Ao usar o Crawl4AI em projetos reais, considere estas práticas:

1. **Respeite o `robots.txt`**: verifique se o site permite scraping antes de começar.
2. **Use rate limiting**: configure intervalos entre requisições para não sobrecarregar servidores.
3. **Prefira extração CSS quando possível**: é mais rápida e não consome tokens de LLM.
4. **Cache durante desenvolvimento**: evite requisições desnecessárias enquanto ajusta o código.
5. **Trate erros**: páginas podem falhar, retornar 403 ou ter estrutura inesperada.
6. **Monitore custos de LLM**: cada extração com LLM consome tokens. Use modelos menores para tarefas simples.

Se você trabalha com [logging](/blog/logging-em-python/) e [tratamento de erros](/blog/tratamento-de-erros-em-python/), esses conhecimentos são essenciais para robustez em projetos de scraping.

## Conclusão

O Crawl4AI traz o web scraping para uma nova era. Em vez de batalhar com seletores frágeis que quebram a cada mudança no HTML, você descreve **o que quer extrair** e deixa o LLM fazer o trabalho pesado de entender a estrutura da página.

Para projetos que precisam extrair dados de sites variados, lidar com conteúdo dinâmico e produzir resultados estruturados, o Crawl4AI é a ferramenta mais produtiva disponível em Python hoje. E para quem já domina scraping tradicional com [BeautifulSoup e requests](/blog/web-scraping-python/), a migração é natural — os conceitos são os mesmos, só a estratégia de extração muda.

Se você quer explorar mais ferramentas modernas do ecossistema Python, confira nossos artigos sobre [Polars](/blog/polars-alternativa-pandas-python/), [Pydantic](/blog/pydantic-validacao-dados-python/) e [automação com Python](/blog/automatizacao-com-python/).

> Para scraping em larga escala com performance máxima, <a href="https://golang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go com Colly oferece crawling concorrente extremamente eficiente com goroutines</a> — ideal para quando você precisa raspar milhões de páginas e o gargalo é a velocidade de rede, não a extração de dados.
