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

# Scrape

> Transformez n’importe quelle URL en Markdown, HTML, captures d’écran, PDF ou JSON structuré prêt pour LLM.

Grâce au point de terminaison `/v1/scrapes` d'Olostep, vous pouvez extraire en temps réel du Markdown, HTML, texte, captures d’écran ou JSON structuré compatible LLM à partir de n’importe quelle URL.

* Produit du markdown propre, des données structurées, des captures d’écran ou du html
* Extraire du JSON via [Parsers](/features/structured-content/parsers) ou [extraction LLM](/features/structured-content/llm-extraction)
* Gère le contenu dynamique : sites rendus en js, flux de connexion via des actions, PDF

Pour les détails de l'API, consultez la [Référence de l'API Scrape](/api-reference/scrapes/create).

## Scraper une URL

Utilisez le point de terminaison `/v1/scrapes` pour scraper une seule URL et choisir les formats de sortie.

### Installation

<CodeGroup>
  ```python Python theme={null}
  pip install olostep
  ```

  ```javascript Node theme={null}
  npm install olostep
  ```

  ```bash cURL theme={null}
  # curl est disponible par défaut sur macOS, Linux et Windows
  ```

  ```javascript Node (API) theme={null}
  npm install node-fetch
  ```

  ```bash Python (API) theme={null}
  pip install requests
  ```
</CodeGroup>

### Utilisation

Vous pouvez utiliser le point de terminaison pour scraper une seule URL et choisir les formats de sortie. Les paramètres obligatoires sont `url_to_scrape` et `formats`.

Parmi les autres paramètres courants, on trouve `wait_before_scraping` (en millisecondes), `remove_css_selectors` (par défaut, aucun, ou un tableau de sélecteurs), et `country`.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://en.wikipedia.org/wiki/Alexander_the_Great",
      formats=["markdown", "html"],
  )

  print(result.markdown_content)
  print(result.html_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://en.wikipedia.org/wiki/Alexander_the_Great',
    formats: ['markdown', 'html'],
  })

  console.log(result.markdown_content)
  console.log(result.html_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
      "formats": ["markdown", "html"]
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://en.wikipedia.org/wiki/Alexander_the_Great" \
    --formats markdown,html
  ```

  ```js Node (API) theme={null}
  const endpoint = 'https://api.olostep.com/v1/scrapes'
  const payload = {
    url_to_scrape: 'https://en.wikipedia.org/wiki/Alexander_the_Great',
    formats: ['markdown', 'html']
  }
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <YOUR_API_KEY>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  })
  const data = await res.json()
  console.log(data)
  ```

  ```python Python (API) theme={null}
  import requests
  import json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
      "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
      "formats": ["markdown", "html"]
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }

  response = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```
</CodeGroup>

### Réponse

L'API retourne un objet `scrape` en réponse.

Le `scrape` possède quelques propriétés comme `id` et `result`.

L'objet `result` a les champs suivants (selon le paramètre `formats`, certains peuvent être nuls) :

* `html_content` : le contenu HTML de la page. Passez `formats: ["html"]` pour obtenir ceci.
* `markdown_content` : le contenu MD de la page. Passez `formats: ["markdown"]` pour obtenir ceci.
* `text_content` : le contenu texte de la page. Passez `formats: ["text"]` pour obtenir ceci.
* `json_content` : le contenu JSON de la page. Passez `formats: ["json"]` pour obtenir ceci et fournissez également un paramètre `parser` ou `llm_extract`.
* `screenshot_hosted_url` : l'URL hébergée de la capture d’écran.
* `html_hosted_url` : l'URL hébergée du contenu HTML
* `markdown_hosted_url` : l'URL hébergée du contenu Markdown
* `json_hosted_url` : l'URL hébergée du contenu JSON
* `text_hosted_url` : l'URL hébergée du contenu texte
* `links_on_page` : les liens sur la page
* `page_metadata` : les métadonnées de la page

```json theme={null}
{
  "id": "scrape_6h89o8u1kt",
  "object": "scrape",
  "created": 1745673871,
  "metadata": {},
  "retrieve_id": "6h89o8u1kt",
  "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
  "result": {
    "html_content": "<html...",
    "markdown_content": "## Alexander the Great...",
    "text_content": null,
    "json_content": null,
    "screenshot_hosted_url": null,
    "html_hosted_url": "https://olostep-storage.s3.us-east-1.amazonaws.com/text_6h89o8u1kt.txt",
    "markdown_hosted_url": "https://olostep-storage.s3.us-east-1.amazonaws.com/markDown_6h89o8u1kt.txt",
    "json_hosted_url": null,
    "text_hosted_url": null,
    "links_on_page": [],
    "page_metadata": { "status_code": 200, "title": "" }
  }
}
```

## Mise en cache

Pour optimiser la vitesse, Olostep fournit une couche de mise en cache partagée en option pour les résultats HTML, Markdown, texte et JSON analysés.

### Comment ça fonctionne

Lorsqu'un scrape est demandé, Olostep vérifie si un scrape correspondant existe déjà avec les mêmes paramètres. Si un match assez récent est trouvé, le contenu est servi instantanément depuis le stockage d'Olostep sans lancer un nouveau scrape de navigateur.

* **Cache partagé :** Le cache est partagé globalement. Si une autre requête a scrappé exactement la même URL avec exactement la même configuration dans votre fenêtre de fraîcheur, vous bénéficiez de l'accélération.
* **Le post-traitement est toujours en direct :** Les opérations comme `llm_extract` et les filtres `links_on_page` sont exécutées *à la volée* sur le document mis en cache. Vous ne mettez en cache que la récupération de la page principale, gardant vos extractions structurées dynamiques.

### Fraîcheur et `max_age`

Par défaut, l'API de production effectue toujours un scrape en direct pour garantir une précision en temps réel. Vous pouvez opter pour la mise en cache en utilisant le paramètre `max_age`.

| Paramètre | Type      | Par défaut | Description                                                                                                                                               |
| --------- | --------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `max_age` | `integer` | `0`        | Âge acceptable du contenu en **secondes**. Si une copie mise en cache existe et est plus récente que `max_age` secondes, elle est servie depuis le cache. |

* **Comportement par défaut de l'API (`max_age: 0`) :** Chaque requête API déclenche un nouveau scrape.
* **Comportement par défaut du Playground :** Dans le playground du tableau de bord, `max_age` est par défaut de 24 heures (`86400` secondes) pour éviter les scrapes redondants et économiser des crédits pendant que vous construisez et testez.
* **Âge maximum :** Le cache a une limite stricte de **7 jours** (`604800` secondes). Tout `max_age` demandé au-dessus de cette limite reviendra à un maximum de 7 jours.

### Exemples d'utilisation

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  # Opter pour la mise en cache : Accepter des résultats jusqu'à 1 jour (86400 secondes) d'ancienneté
  result = client.scrapes.create(
      url_to_scrape="https://example.com",
      formats=["markdown"],
      max_age=86400
  )
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  // Opter pour la mise en cache : Accepter des résultats jusqu'à 1 jour (86400 secondes) d'ancienneté
  const result = await client.scrapes.create({
    url: 'https://example.com',
    formats: ['markdown'],
    maxAge: 86400,
  })
  ```

  ```bash cURL theme={null}
  # Opter pour la mise en cache : Accepter des résultats jusqu'à 1 heure (3600 secondes) d'ancienneté
  curl -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://example.com",
      "formats": ["markdown"],
      "max_age": 3600
    }'
  ```

  ```js Node (API) theme={null}
  const endpoint = 'https://api.olostep.com/v1/scrapes'
  const payload = {
    url_to_scrape: 'https://example.com',
    formats: ['markdown'],
    max_age: 86400 // Accepter des résultats jusqu'à 1 jour (86400 secondes) d'ancienneté
  }
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <YOUR_API_KEY>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  })
  const data = await res.json()
  console.log(data)
  ```

  ```python Python (API) theme={null}
  import requests
  import json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
      "url_to_scrape": "https://example.com",
      "formats": ["markdown"],
      "max_age": 86400 # Accepter des résultats jusqu'à 1 jour (86400 secondes) d'ancienneté
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }

  response = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```
</CodeGroup>

### Quand le cache est-il ignoré ?

Le cache est automatiquement contourné (forçant un scrape en direct) pour les fonctionnalités nécessitant des sessions uniques, des sorties visuelles en temps réel ou une gestion de fichiers personnalisée :

* **Sessions interactives :** Requêtes utilisant `session_id` ou chargeant un `context` de navigateur personnalisé.
* **Visuels :** Outils de visualisation et captures d’écran (`htmlVisualizer`).
* **Types de fichiers spéciaux :** Téléchargements de fichiers binaires ou rendu brut de PDF.
* **Débogage & Réseau :** Capture des `network_calls` ou utilisation de tâches d'analyse asynchrones.

## Extraction de liens

Passez un objet `links_on_page` dans la requête pour collecter les liens trouvés sur la page. Tous les liens sont retournés sous forme d'URL absolues.

```json theme={null}
"links_on_page": {
  "include_links": ["/blog/*"],
  "exclude_links": ["*.pdf"],
  "query_to_order_links_by": "pricing"
}
```

* `include_links` / `exclude_links` : motifs globaux correspondants à chaque chemin d'URL de lien.
* `query_to_order_links_by` : réorganise les liens retournés par pertinence par rapport à ce texte.

<Note>
  Les motifs globaux correspondent aux segments de chemin. Un seul `*` ne traverse **pas** `/`, donc `"/blog/*"` correspond à `"/blog/post-1"` mais **pas** à l'index `"/blog"` lui-même — et ne correspond jamais à `"/blog?tag=x"` car les chaînes de requête ne font pas partie du chemin. Pour inclure également l'index, utilisez `"/blog*"` ou `"{/blog,/blog/**}"`.
</Note>

## Formats de Scrape

Choisissez un ou plusieurs formats de sortie via `formats` :

* `markdown` : markdown compatible LLM
* `html` : HTML nettoyé
* `text` : texte brut
* `json` : sortie structurée (via parser ou llm\_extract)
* `raw_pdf` : octets PDF bruts extraits vers une URL hébergée
* `screenshot` : défini via des actions pour capturer une capture d’écran et retourner une URL hébergée

Les clés de sortie sont retournées à l'intérieur de `result` sous forme de champs `*_content` et d'un `*_hosted_url` également.

## Extraire des données structurées

Vous pouvez extraire du JSON structuré de deux manières : en utilisant des Parsers ou l'extraction LLM.

### Utiliser un Parser (recommandé pour l'échelle)

Définissez `formats: ["json"]` et fournissez un `id` de parser.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
      formats=["json"],
      parser="@olostep/google-search",
  )

  print(result.json_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://www.google.com/search?q=alexander+the+great&gl=us&hl=en',
    formats: ['json'],
    parser: '@olostep/google-search',
  })

  console.log(result.json_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
      "formats": ["json"],
      "parser": {"id": "@olostep/google-search"}
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en" \
    --formats json \
    --payload-json '{"parser":{"id":"@olostep/google-search"}}'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://www.google.com/search?q=alexander+the+great&gl=us&hl=en',
      formats: ['json'],
      parser: { id: '@olostep/google-search' }
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
    "formats": ["json"],
    "parser": { 
      "id": "@olostep/google-search" 
    }
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>", 
      "Content-Type": "application/json"
  }

  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

Olostep propose quelques parsers pré-construits pour les [sites populaires](https://www.olostep.com/store) mais vous pouvez également créer vos propres parsers via le tableau de bord ou demander à notre équipe de le faire pour vous.

Les parsers sont auto-réparateurs et se mettront à jour vers la dernière version du site web.

### Utiliser l'extraction LLM (schéma et/ou prompt)

Fournissez `llm_extract` avec un schéma JSON (`schema`) et/ou une instruction en langage naturel (`prompt`). Vous pouvez passer les deux paramètres, mais si les deux sont fournis, `schema` prend la priorité.

Sinon, si vous passez simplement un `prompt`, le LLM extraira les données en fonction du prompt et décidera de la structure des données par lui-même.

<CodeGroup>
  ```python Python theme={null}
  from olostep import LLMExtract, Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://www.berklee.edu/events/stefano-marchese-friends",
      formats=["markdown", "json"],
      llm_extract=LLMExtract(
          schema={
              "event": {
                  "type": "object",
                  "properties": {
                      "title": {"type": "string"},
                      "date": {"type": "string"},
                      "description": {"type": "string"},
                      "venue": {"type": "string"},
                      "address": {"type": "string"},
                      "start_time": {"type": "string"},
                  },
              }
          }
      ),
  )

  print(result.json_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://www.berklee.edu/events/stefano-marchese-friends',
    formats: ['markdown', 'json'],
    llmExtract: {
      schema: {
        event: {
          type: 'object',
          properties: {
            title: { type: 'string' },
            date: { type: 'string' },
            description: { type: 'string' },
            venue: { type: 'string' },
            address: { type: 'string' },
            start_time: { type: 'string' },
          },
        },
      },
    },
  })

  console.log(result.json_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://www.berklee.edu/events/stefano-marchese-friends",
      "formats": ["json"],
      "llm_extract": {
        "prompt": "Extract the event title, date, description, venue, address, and start time from the page."
      }
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://www.berklee.edu/events/stefano-marchese-friends" \
    --formats json \
    --payload-json '{"llm_extract":{"prompt":"Extract the event title, date, description, venue, address, and start time from the page."}}'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://www.berklee.edu/events/stefano-marchese-friends',
      formats: ['json'],
      llm_extract: {
        prompt: 'Extract the event title, date, description, venue, address, and start time from the page.'
      }
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://www.berklee.edu/events/stefano-marchese-friends",
    "formats": ["markdown", "json"],
    "llm_extract": {
      "schema": {
        "event": {
          "type": "object",
          "properties": {
            "title": {"type": "string"},
            "date": {"type": "string"},
            "description": {"type": "string"},
            "venue": {"type": "string"},
            "address": {"type": "string"},
            "start_time": {"type": "string"}
          }
        }
      }
    }
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }
  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

Note : `result.json_content` retourne un JSON sous forme de chaîne. Analysez-le dans votre code si vous avez besoin d'un objet.

**Tarification :** `llm_extract` coûte 10 crédits par scrape. Pour réduire le coût, vous pouvez apporter vos propres clés API ou activer la tarification basée sur l'utilisation. Contactez [info@olostep.com](mailto:info@olostep.com) pour obtenir l'accès.

## Extraire les liens sur la page

Avec l'option `links_on_page`, vous pouvez extraire tous les liens présents sur la page que vous scrapez. Elle accepte les paramètres suivants pour aider à filtrer et ordonner les liens extraits :

* `absolute_links` (booléen, par défaut : `true`) : Lorsqu'il est vrai, il retourne des URL complètes (par exemple, `https://example.com/page`) au lieu de chemins relatifs (par exemple, `/page`).
* `query_to_order_links_by` (chaîne) : Ordonne les liens retournés par leur similarité avec le texte de requête fourni, en priorisant les correspondances les plus pertinentes en premier.
* `include_links` (tableau de chaînes) : Filtrer les liens extraits en utilisant des motifs globaux. Utilisez des motifs comme `*.pdf` pour correspondre aux extensions de fichiers, `/blog/*` pour des chemins spécifiques, ou des URL complètes comme `https://example.com/*`. Prend en charge les jokers (`*`), les classes de caractères (`[a-z]`), et l'alternance (`{motif1,motif2}`).
* `exclude_links` (tableau de chaînes) : Exclure des liens spécifiques en utilisant des motifs globaux, suivant la même syntaxe que `include_links`.

## Interagir avec la page avec des Actions

Effectuez des actions avant de scraper pour interagir avec des sites dynamiques. Actions prises en charge :

* `wait` avec `milliseconds`
* `click` avec `selector`
* `fill_input` avec `selector` et `value`
* `scroll` avec `direction` et `amount`

Il est souvent utile d'utiliser `wait` avant/après d'autres actions pour permettre le chargement de la page.

### Exemple

<CodeGroup>
  ```python Python theme={null}
  from olostep import FillInputAction, Olostep, WaitAction

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://example.com/login",
      formats=["markdown"],
      actions=[
          FillInputAction(selector="input[type=email]", value="john@example.com"),
          WaitAction(milliseconds=500),
          FillInputAction(selector="input[type=password]", value="secret"),
          {"type": "click", "selector": "button[type=\"submit\"]"},
          WaitAction(milliseconds=1500),
      ],
  )

  print(result.markdown_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://example.com/login',
    formats: ['markdown'],
    actions: [
      { type: 'fill_input', selector: 'input[type=email]', value: 'john@example.com' },
      { type: 'wait', milliseconds: 500 },
      { type: 'fill_input', selector: 'input[type=password]', value: 'secret' },
      { type: 'click', selector: 'button[type="submit"]' },
      { type: 'wait', milliseconds: 1500 },
    ],
  })

  console.log(result.markdown_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://example.com/login",
      "formats": ["markdown"],
      "actions": [
        { "type": "fill_input", "selector": "input[type=email]", "value": "john@example.com" },
        { "type": "wait", "milliseconds": 500 },
        { "type": "fill_input", "selector": "input[type=password]", "value": "secret" },
        { "type": "click", "selector": "button[type=\"submit\"]" },
        { "type": "wait", "milliseconds": 1500 }
      ]
    }'
  ```

  ```bash CLI theme={null}
  # Pour des options complexes comme les actions, utilisez --payload-file avec un fichier JSON
  olostep scrape "https://example.com/login" \
    --formats markdown \
    --payload-file actions.json

  # Où actions.json contient :
  # {
  #   "actions": [
  #     {"type": "fill_input", "selector": "input[type=email]", "value": "john@example.com"},
  #     {"type": "wait", "milliseconds": 500},
  #     {"type": "fill_input", "selector": "input[type=password]", "value": "secret"},
  #     {"type": "click", "selector": "button[type=\"submit\"]"},
  #     {"type": "wait", "milliseconds": 1500}
  #   ]
  # }
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://example.com/login',
      formats: ['markdown'],
      actions: [
        { type: 'fill_input', selector: 'input[type=email]', value: 'john@example.com' },
        { type: 'wait', milliseconds: 500 },
        { type: 'fill_input', selector: 'input[type=password]', value: 'secret' },
        { type: 'click', selector: 'button[type="submit"]' },
        { type: 'wait', milliseconds: 1500 }
      ]
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://example.com/login",
    "formats": ["markdown"],
    "actions": [
      {"type": "fill_input", "selector": "input[type=email]", "value": "john@example.com"},
      {"type": "wait", "milliseconds": 500},
      {"type": "fill_input", "selector": "input[type=password]", "value": "secret"},
      {"type": "click", "selector": "button[type=\"submit\"]"},
      {"type": "wait", "milliseconds": 1500}
    ]
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>", 
      "Content-Type": "application/json"
  }
  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

La réponse inclura tous les formats demandés (par exemple, `markdown_content`).

## Cas d'utilisation

Voici quelques applications pratiques de clients utilisant le point de terminaison `/scrapes`.

### Analyse de contenu & Recherche

* **Analyse concurrentielle** : Extraire les détails des produits, les prix et les caractéristiques des sites concurrents
* **Étude de marché** : Analyser les pages de destination, les descriptions de produits et les témoignages clients
* **Recherche académique** : Rassembler des données spécifiques à partir de publications scientifiques ou de portails de recherche
* **Documentation légale** : Extraire des études de cas, des réglementations ou des précédents juridiques à partir de sites officiels

### E-commerce & Vente au détail

* **Stratégies de tarification dynamique** : Obtenez les prix des produits en temps réel des magasins concurrents
* **Gestion de l'information produit** : Extraire des spécifications détaillées et des descriptions
* **Surveillance des stocks/inventaires** : Vérifiez la disponibilité des produits chez d'autres détaillants
* **Analyse des avis** : Recueillir les retours des consommateurs et le sentiment pour des produits spécifiques

### Marketing & Création de contenu

* **Curation de contenu** : Extraire des articles et des billets de blog pertinents pour des newsletters
* **Analyse SEO** : Examiner l'utilisation des mots-clés des concurrents, les méta-descriptions et la structure des pages
* **Génération de leads** : Extraire des informations de contact à partir d'annuaires d'entreprises ou de pages d'entreprises
* **Recherche d'influenceurs** : Recueillir des métriques d'engagement et des styles de contenu à partir de profils d'influenceurs
* **Génération personnalisée de médias sociaux** : Créer des campagnes de marketing sur les réseaux sociaux alimentées par l'IA en analysant les sites web des clients

### Applications de données

* **Collecte de données d'entraînement IA** : Rassembler des exemples spécifiques pour les modèles d'apprentissage automatique
* **Construction de bases de connaissances personnalisées** : Extraire de la documentation ou des instructions à partir de sites logiciels
* **Archives de données historiques** : Préserver le contenu des sites web à des moments spécifiques
* **Extraction de données structurées** : Transformer le contenu web en ensembles de données formatés pour l'analyse

### Surveillance & Alertes

* **Surveillance de la conformité réglementaire** : Suivre les modifications des sites web légaux ou réglementaires
* **Gestion de crise** : Surveiller les sites d'actualités pour les mentions d'événements ou d'organisations spécifiques
* **Suivi d'événements** : Extraire des détails sur les événements à venir à partir de sites de lieux ou d'organisateurs
* **Surveillance de l'état des services** : Vérifier les pages d'état des services pour des plateformes ou outils spécifiques

### Publication & Médias

* **Agrégation de nouvelles** : Extraire des nouvelles de dernière minute à partir de sources officielles
* **Surveillance des médias** : Suivre des sujets spécifiques sur les sites d'actualités
* **Vérification du contenu** : Extraire des informations pour vérifier les faits ou les déclarations
* **Extraction multimédia** : Recueillir des vidéos, images ou audios intégrés pour des bibliothèques de médias

### Applications financières

* **Recherche d'investissement** : Extraire des états financiers ou des rapports annuels à partir de sites d'entreprises
* **Indicateurs économiques** : Recueillir des données économiques à partir de sites gouvernementaux ou d'institutions financières
* **Données sur les cryptomonnaies** : Extraire des informations en temps réel sur les prix et la capitalisation boursière
* **Analyse des nouvelles financières** : Surveiller les sites d'actualités financières pour des signaux de marché spécifiques

### Applications techniques

* **Extraction de documentation API** : Recueillir de la documentation technique pour référence
* **Tests d'intégration** : Extraire des éléments de site web pour vérifier les intégrations tierces
* **Tests d'accessibilité** : Analyser la structure des sites web pour la conformité aux normes d'accessibilité
* **Création d'archives web** : Capturer le contenu complet des sites web pour la préservation historique

### Scénarios d'intégration

* **Systèmes CRM** : Améliorer les profils clients avec des données provenant de sites d'entreprises ou de Linkedin
* **Systèmes de gestion de contenu** : Importer du contenu externe pertinent
* **Outils de Business Intelligence** : Compléter les données internes avec des informations de marché externes
* **Logiciels de gestion de projet** : Extraire des spécifications ou des exigences à partir de sites clients
* **Tableaux de bord personnalisés** : Afficher les données extraites aux côtés des métriques internes

## Gestion des erreurs

Toutes les erreurs suivent une forme d'enveloppe partagée. Vérifiez `error.type` et `error.code` pour brancher de manière programmatique :

```json theme={null}
{
  "id": "error_abc123",
  "object": "error",
  "created": 1745673871,
  "url": "https://example.com",
  "metadata": {},
  "error": {
    "type": "...",
    "code": "...",
    "message": "..."
  }
}
```

| HTTP | `error.type`            | `error.code`            | Signification                                                                                                 |
| ---- | ----------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| 400  | `invalid_request_error` | `dns_resolution_failed` | Le domaine n'existe pas ou l'URL contient une faute de frappe.                                                |
| 400  | `invalid_request_error` | `invalid_url`           | L'URL est mal formée.                                                                                         |
| 502  | `invalid_request_error` | `tls_error`             | Le site web a un certificat TLS/SSL invalide ou incompatible. `error.detail` contient le code SSL bas niveau. |
| 504  | `request_timeout`       | `scrape_poll_timeout`   | Le scrape n'a pas terminé dans le budget d'attente d'environ 55 secondes.                                     |

### Échec DNS (400)

Le domaine ne résout pas. Vérifiez l'URL pour des fautes de frappe.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "dns_resolution_failed",
    "message": "L'URL contient une faute de frappe, ou le domaine n'existe pas."
  }
}
```

### Erreur TLS/SSL (502)

Le site cible a une configuration HTTPS cassée ou incompatible. `error.detail` fournit le code d'erreur SSL spécifique pour le diagnostic ; `error.code` est toujours `tls_error`.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "tls_error",
    "detail": "err_ssl_tlsv1_alert_internal_error",
    "message": "Le site web a fermé ou rejeté la poignée de main TLS. Le serveur peut être mal configuré ou utiliser une version SSL/TLS non prise en charge."
  }
}
```

### Délai d'attente de la requête (504)

Le scrape n'a pas été complété dans le budget d'attente. La page peut être lente, protégée contre les robots, ou temporairement indisponible. Cette réponse est sûre à réessayer.

```json theme={null}
{
  "error": {
    "type": "request_timeout",
    "code": "scrape_poll_timeout",
    "message": "La requête a expiré en attendant le résultat du scrape. La page peut être lente, bloquée pour nos fetchers, ou temporairement indisponible."
  }
}
```

## Tarification

Scrape coûte 1 crédit par défaut. Si vous passez également des [parsers](/features/structured-content/parsers), les coûts varient selon le parser (1-5 crédits). Si vous utilisez [LLM extract](/features/structured-content/llm-extraction), cela coûte 10 crédits.
