> ## 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

> Le SDK Python de Firecrawl est une surcouche à l’API Firecrawl qui vous aide à convertir facilement des sites web en Markdown.

<div id="installation">
  ## Installation
</div>

Pour installer le SDK Python Firecrawl, utilisez pip :

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

from firecrawl import Firecrawl

firecrawl = Firecrawl(
  # Aucune clé API requise pour démarrer — ajoutez-en une pour des limites de débit plus élevées :
  # api_key="fc-YOUR-API-KEY",
)
```

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

Récupérez une clé API sur [firecrawl.dev](https://firecrawl.dev), puis définissez-la comme variable d’environnement `FIRECRAWL_API_KEY` ou passez-la directement à la classe `Firecrawl`.

<Note>
  **Pas de clé API ?** Vous pouvez instancier `Firecrawl` sans clé et utiliser `scrape`, `search` et `interact` dans l’offre Free sans clé (avec une limite de débit par IP — voir [Limites de débit](/fr/rate-limits#keyless-no-api-key)). Toutes les autres méthodes nécessitent une clé.
</Note>

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

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

# Extraire le contenu d’un site :
scrape_status = firecrawl.scrape(
  'https://firecrawl.dev', 
  formats=['markdown', 'html']
)
print(scrape_status)

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

<div id="scraping-a-url">
  ### Extraction d’une URL
</div>

Pour extraire une URL unique, utilisez la méthode `scrape`. Elle renvoie le contenu de la page sous forme de donnée structurée, y compris le markdown, les métadonnées et tous les autres formats demandés.

```python Python theme={null}
# Extraire un site web :
scrape_result = firecrawl.scrape('firecrawl.dev', formats=['markdown', 'html'])
print(scrape_result)
```

<Note>
  Le SDK Python convertit tous les noms de champs de la réponse de camelCase en snake\_case. Par exemple, les champs de métadonnées tels que `ogImage`, `ogTitle` et `sourceURL` de l’API deviennent `og_image`, `og_title` et `source_url` dans la réponse du SDK.
</Note>

<div id="parsing-uploaded-files">
  ### Analyse des fichiers envoyés
</div>

Utilisez `parse` pour envoyer des fichiers locaux (`html`, `pdf`, `docx`, `xlsx`, etc.) directement à `/v2/parse`.
`parse` ne prend pas en charge `changeTracking` ni les options réservées au navigateur, comme actions, wait\_for, location, mobile, screenshot et 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">
  ### Explorer un site web
</div>

Pour explorer un site web, utilisez la méthode `crawl`. Elle prend en arguments l’URL de départ et des options facultatives. Ces options permettent de définir des paramètres supplémentaires pour la tâche d’exploration, comme le nombre maximal de pages à parcourir, les domaines autorisés et le format de sortie. Consultez [Pagination](#pagination) pour la pagination automatique/manuelle et les 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">
  ### Exploration du sitemap uniquement
</div>

Utilisez `sitemap="only"` pour explorer uniquement les URL du sitemap (l’URL de départ est toujours incluse et la découverte de liens HTML est ignorée).

```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">
  ### Démarrer un crawl
</div>

<Tip>Vous préférez ne pas bloquer l’exécution ? Consultez la section [Classe Async](#async-class) ci-dessous.</Tip>

Lancez une tâche sans attendre avec `start_crawl`. Elle renvoie un `ID` de tâche que vous pouvez utiliser pour vérifier l’état. Utilisez `crawl` lorsque vous voulez un attenteur qui bloque jusqu’à la fin. Voir [Pagination](#pagination) pour le comportement et les limites de pagination.

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

<div id="checking-crawl-status">
  ### Vérifier l’état d’un crawl
</div>

Vérifiez l’état d’une tâche de crawl avec `get_crawl_status`. Indiquez l’ID de tâche pour obtenir l’état actuel ainsi que les résultats déjà collectés.

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

<div id="cancelling-a-crawl">
  ### Annuler un crawl
</div>

Annulez une tâche de crawl avec la méthode `cancel_crawl`. Passez l’ID de tâche renvoyé par `start_crawl` pour obtenir l’état de l’annulation.

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

<div id="map-a-website">
  ### Cartographier un site web
</div>

Utilisez `map` pour générer une liste d’URL à partir d’un site web. Les options permettent d’adapter le processus de cartographie, par exemple en excluant les sous-domaines ou en s’appuyant sur le sitemap.

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

<div id="crawling-a-website-with-websockets">
  ### Exploration d’un site web avec WebSockets
</div>

Pour explorer un site web avec WebSockets, lancez la tâche avec `start_crawl` et abonnez-vous à l’aide du helper `watcher`. Créez un watcher avec l’ID de la tâche et attachez des gestionnaires (par exemple pour page, completed, failed) avant d’appeler `start()`.

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

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

    # Démarrer d'abord un crawl
    started = await firecrawl.start_crawl("https://firecrawl.dev", limit=5)

    # Surveiller les mises à jour (instantanés) jusqu'au statut final
    async for snapshot in firecrawl.watcher(started.id, kind="crawl", poll_interval=2, timeout=120):
        if snapshot.status == "completed":
            print("DONE", snapshot.status)
            for doc in snapshot.data:
                print("DOC", doc.metadata.source_url if doc.metadata else None)
        elif snapshot.status == "failed":
            print("ERR", snapshot.status)
        else:
            print("STATUS", snapshot.status, snapshot.completed, "/", snapshot.total)

asyncio.run(main())
```

<div id="pagination">
  ### Pagination
</div>

Les points de terminaison Firecrawl pour crawl et batch scrape renvoient une URL `next` lorsqu’il reste des données. Le SDK Python effectue par défaut une pagination automatique et agrège tous les documents ; dans ce cas, `next` vaut `None`. Vous pouvez désactiver l’auto‑pagination ou définir des limites pour contrôler le comportement de la pagination.

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

Utilisez `PaginationConfig` pour contrôler le comportement de la pagination lorsque vous appelez `get_crawl_status` ou `get_batch_scrape_status` :

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

| Option          | Type   | Par défaut | Description                                                                                                                                     |
| --------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `auto_paginate` | `bool` | `True`     | Lorsque `True`, récupère automatiquement toutes les pages et agrège les résultats. Définissez sur `False` pour récupérer les pages une par une. |
| `max_pages`     | `int`  | `None`     | S'arrête après avoir récupéré ce nombre de pages (s'applique uniquement lorsque `auto_paginate=True`).                                          |
| `max_results`   | `int`  | `None`     | S'arrête après avoir collecté ce nombre de documents (s'applique uniquement lorsque `auto_paginate=True`).                                      |
| `max_wait_time` | `int`  | `None`     | S'arrête après ce nombre de secondes (s'applique uniquement lorsque `auto_paginate=True`).                                                      |

<div id="manual-pagination-helpers">
  #### Aides à la pagination manuelle
</div>

Lorsque `auto_paginate=False`, la réponse inclut une URL `next` si davantage de données sont disponibles. Utilisez ces méthodes utilitaires pour récupérer les pages suivantes :

* **`get_crawl_status_page(next_url)`** - Récupère la page suivante des résultats de crawl en utilisant l'URL opaque `next` provenant d'une réponse précédente.
* **`get_batch_scrape_status_page(next_url)`** - Récupère la page suivante des résultats de scraping par lot en utilisant l'URL opaque `next` provenant d'une réponse précédente.

Ces méthodes renvoient le même type de réponse que l'appel de statut initial, y compris une nouvelle URL `next` s'il reste d'autres pages.

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

Utilisez la méthode « waiter » `crawl` pour l’approche la plus simple, ou démarrez un job et paginez manuellement.

<div id="simple-crawl-auto-pagination-default">
  ##### Crawl simple (pagination automatique, par défaut)
</div>

* Voir le flux par défaut dans [Explorer un site web](#crawl-a-website).

<div id="manual-crawl-with-pagination-control">
  ##### Crawl manuel avec contrôle de la pagination
</div>

Démarrez un job, puis récupérez une page à la fois avec `auto_paginate=False`. Utilisez `get_crawl_status_page` pour récupérer les pages suivantes :

```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")

# Récupérer les pages suivantes avec 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">
  ##### Exploration manuelle avec limites (pagination automatique + arrêt anticipé)
</div>

Laissez la pagination automatique activée, mais arrêtez plus tôt avec `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("crawl limité :", status.status, "docs :", len(status.data), "suivant :", status.next)
```

<div id="batch-scrape">
  #### Scrape par lots
</div>

Utilisez la méthode de waiter `batch_scrape`, ou lancez un job et paginez manuellement.

<div id="simple-batch-scrape-auto-pagination-default">
  ##### Extraction par lot simple (pagination automatique, par défaut)
</div>

* Voir le parcours par défaut dans [Batch Scrape](/fr/features/batch-scrape).

<div id="manual-batch-scrape-with-pagination-control">
  ##### Scraping par lot manuel avec contrôle de la pagination
</div>

Lancez une tâche, puis récupérez les résultats page par page avec `auto_paginate=False`. Utilisez `get_batch_scrape_status_page` pour récupérer les pages suivantes :

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

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

# Récupérer les pages suivantes avec get_batch_scrape_status_page
while status.next:
    status = client.get_batch_scrape_status_page(status.next)
    print("Next page:", len(status.data), "docs")
```

<div id="manual-batch-scrape-with-limits-auto-pagination-early-stop">
  ##### Extraction par lots manuelle avec limites (pagination automatique + arrêt anticipé)
</div>

Laissez la pagination automatique activée, mais arrêtez plus tôt avec `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("lot limité :", status.status, "docs :", len(status.data), "suivant :", status.next)
```

<div id="error-handling">
  ## Gestion des erreurs
</div>

Lorsqu'une requête échoue, le SDK lève une exception accompagnée d'un message descriptif indiquant l'origine du problème. Entourez vos appels de `try`/`except` pour intercepter ces exceptions et gérer les erreurs dans votre application.

<div id="async-class">
  ## Classe asynchrone
</div>

Pour les opérations asynchrones, utilisez la classe `AsyncFirecrawl`. Ses méthodes reprennent celles de `Firecrawl`, mais elles ne bloquent pas le thread principal.

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

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

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

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

    # Crawl (démarrage + statut)
    started = await firecrawl.start_crawl("https://docs.firecrawl.dev", limit=3)
    status = await firecrawl.get_crawl_status(started.id)
    print(status.status)

    # Scraping par lot (attente)
    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">
  ## Navigateur
</div>

Lancez des sessions de navigateur dans le cloud et exécutez du code à distance.

<div id="create-a-session">
  ### Créer une session
</div>

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

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

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

<div id="execute-code">
  ### Exécuter du code
</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"
```

Exécuter JavaScript plutôt que 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">
  ### Profils
</div>

Enregistrez et réutilisez l'état du navigateur (cookies, localStorage, etc.) d'une session à l'autre :

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

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

Pour un contrôle total de Playwright, connectez-vous directement en utilisant l’URL du 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">
  ### Lister & fermer des sessions
</div>

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

# Fermer une session
app.delete_browser(session.id)
```

<div id="scrape-bound-interactive-session">
  ### Session interactive liée au scrape
</div>

Utilisez un ID de tâche de scrape pour continuer à interagir avec le contexte de page rejoué issu de ce scrape :

* `interact(job_id, ...)` exécute du code dans la session de navigateur liée au scrape.
* Le premier appel à `interact` initialise automatiquement la session à partir du contexte du scrape.
* Les appels suivants à `interact` sur le même ID de tâche réutilisent cet état actif du navigateur.
* `stop_interaction(job_id)` arrête la session interactive une fois que vous avez terminé.

```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)
```

> Êtes-vous un agent IA qui a besoin d’une clé API Firecrawl ? Consultez [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) pour obtenir les instructions d’intégration automatisée.
