> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firecrawl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Python

> O Firecrawl Python SDK é um encapsulador da Firecrawl API que ajuda você a transformar sites em Markdown com facilidade.

<div id="installation">
  ## Instalação
</div>

Para instalar o SDK do Firecrawl para Python, você pode usar o pip:

```python Python theme={null}
# pip install firecrawl-py

from firecrawl import Firecrawl

firecrawl = Firecrawl(
  # Nenhuma API key necessária para começar — adicione uma para limites de taxa mais altos:
  # api_key="fc-YOUR-API-KEY",
)
```

<div id="usage">
  ## Uso
</div>

Obtenha uma chave de API em [firecrawl.dev](https://firecrawl.dev) e, em seguida, configure-a como uma variável de ambiente chamada `FIRECRAWL_API_KEY` ou passe-a diretamente para a classe `Firecrawl`.

<Note>
  **Sem chave de API?** Você pode instanciar `Firecrawl` sem uma chave e usar `scrape`, `search` e `interact` no plano Free sem chave (com limite de taxa por IP — consulte [Limites de taxa](/pt-BR/rate-limits#keyless-no-api-key)). Todos os outros métodos exigem uma chave.
</Note>

```python Python theme={null}
from firecrawl import Firecrawl

firecrawl = Firecrawl(api_key="fc-YOUR_API_KEY")

# Fazer scraping de um site:
scrape_status = firecrawl.scrape(
  'https://firecrawl.dev', 
  formats=['markdown', 'html']
)
print(scrape_status)

# Fazer crawling de um site:
crawl_status = firecrawl.crawl(
  'https://firecrawl.dev', 
  limit=100, 
  scrape_options={
    'formats': ['markdown', 'html']
  }
)
print(crawl_status)
```

<div id="scraping-a-url">
  ### Fazendo scraping de uma URL
</div>

Faça scraping de uma única URL com o método `scrape`. Ele retorna o conteúdo da página como dados estruturados, incluindo markdown, metadados e quaisquer outros formatos que você solicitar.

```python Python theme={null}
# Fazer scraping de um site:
scrape_result = firecrawl.scrape('firecrawl.dev', formats=['markdown', 'html'])
print(scrape_result)
```

<Note>
  O SDK de Python converte todos os nomes dos campos da resposta de camelCase para snake\_case. Por exemplo, campos de metadados como `ogImage`, `ogTitle` e `sourceURL` da API se tornam `og_image`, `og_title` e `source_url` na resposta do SDK.
</Note>

<div id="parsing-uploaded-files">
  ### Análise de arquivos carregados
</div>

Use `parse` para fazer upload de arquivos locais (`html`, `pdf`, `docx`, `xlsx`, etc.) diretamente para `/v2/parse`.
`parse` não oferece suporte a `changeTracking` nem a opções disponíveis apenas no navegador, como actions, wait\_for, location, mobile, screenshot e branding.

```python Python theme={null}
from firecrawl.v2.types import ParseOptions

parsed = firecrawl.parse(
    b"<!DOCTYPE html><html><body><h1>Python Parse</h1></body></html>",
    filename="upload.html",
    content_type="text/html",
    options=ParseOptions(formats=["markdown"]),
)

print(parsed.markdown)
```

<div id="crawl-a-website">
  ### Rastrear um site
</div>

Para rastrear um site, use o método `crawl`. Ele recebe a URL inicial e, opcionalmente, um objeto de opções. Essas opções permitem definir configurações adicionais para a tarefa de rastreamento, como o número máximo de páginas, os domínios permitidos e o formato de saída. Consulte [Paginação](#pagination) para detalhes sobre paginação automática/manual e limites.

```python Python theme={null}
job = firecrawl.crawl(url="https://docs.firecrawl.dev", limit=5, poll_interval=1, timeout=120)
print(job)
```

<div id="sitemap-only-crawl">
  ### Rastreamento Apenas do Sitemap
</div>

Use `sitemap="only"` para rastrear apenas as URLs do sitemap (a URL inicial é sempre incluída e a descoberta de links em HTML é ignorada).

```python Python theme={null}
job = firecrawl.crawl(url="https://docs.firecrawl.dev", sitemap="only", limit=25)
print(job.status, len(job.data))
```

<div id="start-a-crawl">
  ### Iniciar um crawl
</div>

<Tip>Prefere não bloquear? Veja a seção [Classe assíncrona](#async-class) abaixo.</Tip>

Inicie uma tarefa sem esperar usando `start_crawl`. Ela retorna um `ID` de tarefa que você pode usar para verificar o status. Use `crawl` quando quiser um aguardador que bloqueia até a conclusão. Consulte [Paginação](#pagination) para o comportamento e os limites de paginação.

```python Python theme={null}
job = firecrawl.start_crawl(url="https://docs.firecrawl.dev", limit=10)
print(job)
```

<div id="checking-crawl-status">
  ### Verificando o status do rastreamento
</div>

Consulte o status de um job de rastreamento com `get_crawl_status`. Informe o ID do job e receba o status atual junto com os resultados coletados até o momento.

```python Python theme={null}
status = firecrawl.get_crawl_status("<crawl-id>")
print(status)
```

<div id="cancelling-a-crawl">
  ### Cancelando um Rastreamento
</div>

Cancele um job de rastreamento com o método `cancel_crawl`. Passe o ID do job retornado por `start_crawl` para receber o status do cancelamento.

```python Python theme={null}
ok = firecrawl.cancel_crawl("<crawl-id>")
print("Cancelado:", ok)
```

<div id="map-a-website">
  ### Mapear um site
</div>

Use `map` para gerar uma lista de URLs de um site. As opções permitem personalizar o processo de mapeamento, incluindo excluir subdomínios ou usar o sitemap.

```python Python theme={null}
res = firecrawl.map(url="https://firecrawl.dev", limit=10)
print(res)
```

<div id="crawling-a-website-with-websockets">
  ### Rastreamento de um site com WebSockets
</div>

Para rastrear um site com WebSockets, inicie a tarefa com `start_crawl` e faça a inscrição usando o helper `watcher`. Crie um watcher com o ID da tarefa e vincule handlers (por exemplo, para page, completed, failed) antes de chamar `start()`.

```python Python theme={null}
import asyncio
from firecrawl import AsyncFirecrawl

async def main():
    firecrawl = AsyncFirecrawl(api_key="fc-YOUR-API-KEY")

    # Inicia um crawl primeiro
    started = await firecrawl.start_crawl("https://firecrawl.dev", limit=5)

    # Monitora atualizações (snapshots) até status final
    async for snapshot in firecrawl.watcher(started.id, kind="crawl", poll_interval=2, timeout=120):
        if snapshot.status == "completed":
            print("CONCLUÍDO", snapshot.status)
            for doc in snapshot.data:
                print("DOC", doc.metadata.source_url if doc.metadata else None)
        elif snapshot.status == "failed":
            print("ERRO", snapshot.status)
        else:
            print("STATUS", snapshot.status, snapshot.completed, "/", snapshot.total)

asyncio.run(main())
```

<div id="pagination">
  ### Paginação
</div>

Os endpoints do Firecrawl para crawl e batch scrape retornam uma URL `next` quando há mais dados disponíveis. O SDK Python pagina automaticamente por padrão e agrega todos os documentos; nesse caso, `next` será `None`. Você pode desativar a paginação automática ou definir limites para controlar o comportamento da paginação.

<div id="paginationconfig">
  #### PaginationConfig
</div>

Use `PaginationConfig` para controlar o comportamento da paginação ao chamar `get_crawl_status` ou `get_batch_scrape_status`:

```python Python theme={null}
from firecrawl.v2.types import PaginationConfig
```

| Option          | Type   | Default | Description                                                                                                                                     |
| --------------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `auto_paginate` | `bool` | `True`  | Quando definido como `True`, busca automaticamente todas as páginas e agrega os resultados. Defina como `False` para buscar uma página por vez. |
| `max_pages`     | `int`  | `None`  | Encerra após buscar esse número de páginas (aplica-se somente quando `auto_paginate=True`).                                                     |
| `max_results`   | `int`  | `None`  | Encerra após coletar esse número de documentos (aplica-se somente quando `auto_paginate=True`).                                                 |
| `max_wait_time` | `int`  | `None`  | Encerra após esse número de segundos (aplica-se somente quando `auto_paginate=True`).                                                           |

<div id="manual-pagination-helpers">
  #### Auxiliares para Paginação Manual
</div>

Quando `auto_paginate=False`, a resposta inclui uma URL `next` se houver mais dados disponíveis. Use estes métodos auxiliares para obter as páginas subsequentes:

* **`get_crawl_status_page(next_url)`** - Obtém a próxima página de resultados de crawl usando a URL `next` opaca de uma resposta anterior.
* **`get_batch_scrape_status_page(next_url)`** - Obtém a próxima página de resultados de batch scrape usando a URL `next` opaca de uma resposta anterior.

Esses métodos retornam o mesmo tipo de resposta da chamada de status original, incluindo uma nova URL `next` se restarem mais páginas.

<div id="crawl">
  #### Crawl
</div>

Use o método de espera `crawl` para a experiência mais simples ou inicie um job e faça a paginação manualmente.

<div id="simple-crawl-auto-pagination-default">
  ##### Rastreamento simples (paginação automática, padrão)
</div>

* Veja o fluxo padrão em [Rastrear um site](#crawl-a-website).

<div id="manual-crawl-with-pagination-control">
  ##### Rastreamento manual com controle de paginação
</div>

Inicie um job e, em seguida, recupere uma página por vez com `auto_paginate=False`. Use `get_crawl_status_page` para recuperar as páginas subsequentes:

```python Python theme={null}
crawl_job = client.start_crawl("https://example.com", limit=100)

# Fetch first page
status = client.get_crawl_status(
    crawl_job.id,
    pagination_config=PaginationConfig(auto_paginate=False)
)
print("First page:", len(status.data), "docs")

# Busca páginas subsequentes usando get_crawl_status_page
while status.next:
    status = client.get_crawl_status_page(status.next)
    print("Next page:", len(status.data), "docs")
```

<div id="manual-crawl-with-limits-auto-pagination-early-stop">
  ##### Rastreamento manual com limites (paginação automática + interrupção antecipada)
</div>

Mantenha a paginação automática ativada, mas interrompa antecipadamente com `max_pages`, `max_results` ou `max_wait_time`:

```python Python theme={null}
status = client.get_crawl_status(
    crawl_job.id,
    pagination_config=PaginationConfig(max_pages=2, max_results=50, max_wait_time=15),
)
print("rastreamento limitado:", status.status, "docs:", len(status.data), "próximo:", status.next)
```

<div id="batch-scrape">
  #### Coleta em lote
</div>

Use o método waiter `batch_scrape` ou inicie um job e faça a paginação manualmente.

<div id="simple-batch-scrape-auto-pagination-default">
  ##### Coleta em lote simples (paginação automática, padrão)
</div>

* Veja o fluxo padrão em [Coleta em Lote](/pt-BR/features/batch-scrape).

<div id="manual-batch-scrape-with-pagination-control">
  ##### Raspagem em lote manual com controle de paginação
</div>

Inicie um job e, em seguida, recupere uma página por vez com `auto_paginate=False`. Use `get_batch_scrape_status_page` para obter as páginas subsequentes:

```python Python theme={null}
batch_job = client.start_batch_scrape(urls)

# Buscar primeira página
status = client.get_batch_scrape_status(
    batch_job.id,
    pagination_config=PaginationConfig(auto_paginate=False)
)
print("Primeira página:", len(status.data), "docs")

# Buscar páginas subsequentes usando get_batch_scrape_status_page
while status.next:
    status = client.get_batch_scrape_status_page(status.next)
    print("Próxima página:", len(status.data), "docs")
```

<div id="manual-batch-scrape-with-limits-auto-pagination-early-stop">
  ##### Coleta manual em lote com limites (paginação automática + parada antecipada)
</div>

Deixe a paginação automática ativada, mas interrompa antes usando `max_pages`, `max_results` ou `max_wait_time`:

```python Python theme={null}
status = client.get_batch_scrape_status(
    batch_job.id,
    pagination_config=PaginationConfig(max_pages=2, max_results=100, max_wait_time=20),
)
print("lote limitado:", status.status, "docs:", len(status.data), "próximo:", status.next)
```

<div id="error-handling">
  ## Tratamento de erros
</div>

Quando uma requisição falha, o SDK lança uma exceção com uma mensagem descritiva explicando o que deu errado. Coloque as chamadas em `try`/`except` para capturar essas exceções e tratar as falhas na sua aplicação.

<div id="async-class">
  ## Classe assíncrona
</div>

Para operações assíncronas, use a classe `AsyncFirecrawl`. Seus métodos espelham os de `Firecrawl`, mas não bloqueiam a thread principal.

```python Python theme={null}
import asyncio
from firecrawl import AsyncFirecrawl

async def main():
    firecrawl = AsyncFirecrawl(api_key="fc-YOUR-API-KEY")

    # Extração
    doc = await firecrawl.scrape("https://firecrawl.dev", formats=["markdown"])  # type: ignore[arg-type]
    print(doc.get("markdown"))

    # Busca
    results = await firecrawl.search("firecrawl", limit=2)
    print(results.get("web", []))

    # Rastreamento (início + status)
    started = await firecrawl.start_crawl("https://docs.firecrawl.dev", limit=3)
    status = await firecrawl.get_crawl_status(started.id)
    print(status.status)

    # Extração em lote (aguardando)
    job = await firecrawl.batch_scrape([
        "https://firecrawl.dev",
        "https://docs.firecrawl.dev",
    ], formats=["markdown"], poll_interval=1, timeout=60)
    print(job.status, job.completed, job.total)

asyncio.run(main())
```

```python Python theme={null}
from firecrawl import AsyncFirecrawl

async_firecrawl = AsyncFirecrawl(api_key="fc-YOUR-API-KEY")

parsed = await async_firecrawl.parse(
    b"<!DOCTYPE html><html><body><h1>Async Parse</h1></body></html>",
    filename="upload.html",
    content_type="text/html",
)
```

<div id="browser">
  ## Browser
</div>

Inicie sessões de navegador na nuvem e execute código remotamente.

<div id="create-a-session">
  ### Criar sessão
</div>

```python Python theme={null}
from firecrawl import Firecrawl

app = Firecrawl(api_key="fc-YOUR-API-KEY")

session = app.browser()
print(session.id)             # ID da sessão
print(session.cdp_url)        # wss://cdp-proxy.firecrawl.dev/cdp/...
print(session.live_view_url)  # https://liveview.firecrawl.dev/...
```

<div id="execute-code">
  ### Executar código
</div>

```python Python theme={null}
result = app.browser_execute(
    session.id,
    code='await page.goto("https://news.ycombinator.com")\ntitle = await page.title()\nprint(title)',
    language="python",
)
print(result.result)  # "Hacker News"
```

Execute JavaScript em vez de Python:

```python Python theme={null}
result = app.browser_execute(
    session.id,
    code='await page.goto("https://example.com"); const t = await page.title(); console.log(t);',
    language="node",
)
```

<div id="profiles">
  ### Perfis
</div>

Salve e reutilize o estado do navegador (cookies, localStorage, etc.) em várias sessões:

```python Python theme={null}
session = app.browser(
    ttl=600,
    profile={
        "name": "my-profile",
        "save_changes": True,
    },
)
```

<div id="connect-via-cdp">
  ### Conectar via CDP
</div>

Para ter controle total do Playwright, conecte-se diretamente usando a URL do CDP:

```python Python theme={null}
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(session.cdp_url)
    context = browser.contexts[0]
    page = context.pages[0] if context.pages else context.new_page()

    page.goto("https://example.com")
    print(page.title())

    browser.close()
```

<div id="list-close-sessions">
  ### Listar & Fechar Sessões
</div>

```python Python theme={null}
# List active sessions
sessions = app.list_browsers(status="active")
for s in sessions.sessions:
    print(s.id, s.status, s.created_at)

# Close a session
app.delete_browser(session.id)
```

<div id="scrape-bound-interactive-session">
  ### Sessão interativa vinculada ao scraping
</div>

Use um ID do job de scraping para continuar interagindo com o contexto da página reproduzida a partir desse scraping:

* `interact(job_id, ...)` executa código na sessão do navegador vinculada ao scraping.
* A primeira chamada de `interact` inicializa automaticamente a sessão com base no contexto do scraping.
* Chamadas adicionais de `interact` no mesmo ID do job reutilizam esse estado ativo do navegador.
* `stop_interaction(job_id)` encerra a sessão interativa quando você terminar.

```python Python theme={null}
doc = app.scrape(
    "https://example.com",
    actions=[{"type": "click", "selector": "a[href='/pricing']"}],
)

scrape_job_id = doc.metadata_typed.scrape_id
if not scrape_job_id:
    raise RuntimeError("Missing scrape job id")

run = app.interact(
    scrape_job_id,
    code="print(await page.url())",
    language="python",
    timeout=60,
)
print(run.stdout)

app.stop_interaction(scrape_job_id)
```

> Você é um agente de IA que precisa de uma chave de API do Firecrawl? Consulte [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) para ver instruções de configuração automatizada.
