Extraction de tableaux et structure
Les tableaux : le point faible de l’OCR classique
L’extraction de tableaux est historiquement l’un des problèmes les plus difficiles en OCR. Les solutions traditionnelles comme Tesseract ne comprennent pas la notion de structure tabulaire : elles extraient le texte ligne par ligne, sans préserver les relations entre colonnes et rangées.
OCR 3 change fondamentalement la donne grâce à sa compréhension visuelle de la page.
Le paramètre table_format
Vous contrôlez le format de sortie des tableaux via le paramètre table_format :
import os
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
# Format Markdown (recommandé pour la plupart des cas)
ocr_response = client.ocr.process(
model="mistral-ocr-latest",
document={
"type": "document_url",
"document_url": "https://exemple.com/rapport-financier.pdf"
},
table_format="markdown"
)
Les trois options
1. null (défaut) — Tableaux en ligne
Les tableaux sont intégrés directement dans le flux Markdown sans formatage tabulaire spécifique. Utile quand vous ne traitez pas de documents tabulaires.
2. "markdown" — Tableaux Markdown
Les tableaux sont rendus en format Markdown standard avec pipes :
| Produit | Quantité | Prix unitaire | Total |
|---------|----------|---------------|-------|
| Widget A | 100 | 12,50 € | 1 250 € |
| Widget B | 50 | 25,00 € | 1 250 € |
| **Total** | **150** | | **2 500 €** |
3. "html" — Tableaux HTML
Les tableaux sont rendus en HTML complet, préservant les fusions de cellules et la mise en forme avancée :
<table>
<thead>
<tr>
<th>Produit</th>
<th>Quantité</th>
<th>Prix unitaire</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget A</td>
<td>100</td>
<td>12,50 €</td>
<td>1 250 €</td>
</tr>
</tbody>
</table>
Quand utiliser quel format ?
- Markdown : pour l’indexation RAG, la recherche, l’affichage dans un éditeur Markdown
- HTML : pour les tableaux complexes avec cellules fusionnées, ou pour l’intégration web
- null : quand les tableaux ne sont pas importants dans votre workflow
Extraction et parsing des tableaux
Voici un script complet pour extraire les tableaux et les convertir en données structurées :
import os
import re
import json
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def extraire_tableaux_markdown(markdown: str) -> list[list[list[str]]]:
"""Extrait les tableaux Markdown et les convertit en listes."""
tableaux = []
lignes = markdown.split("\n")
tableau_courant = []
dans_tableau = False
for ligne in lignes:
if "|" in ligne and ligne.strip().startswith("|"):
# Ignorer la ligne de séparation (|---|---|)
if re.match(r"^\|[\s\-:|]+\|$", ligne.strip()):
continue
cellules = [
c.strip() for c in ligne.strip().strip("|").split("|")
]
tableau_courant.append(cellules)
dans_tableau = True
else:
if dans_tableau and tableau_courant:
tableaux.append(tableau_courant)
tableau_courant = []
dans_tableau = False
if tableau_courant:
tableaux.append(tableau_courant)
return tableaux
# Extraction OCR avec tableaux Markdown
ocr_response = client.ocr.process(
model="mistral-ocr-latest",
document={
"type": "document_url",
"document_url": "https://exemple.com/facture.pdf"
},
table_format="markdown"
)
# Parcours des pages et extraction des tableaux
for page in ocr_response.pages:
tableaux = extraire_tableaux_markdown(page.markdown)
for i, tableau in enumerate(tableaux):
print(f"Page {page.index + 1}, Tableau {i + 1}:")
print(json.dumps(tableau, indent=2, ensure_ascii=False))
Conversion en DataFrame pandas
Pour une analyse plus poussée, convertissez directement en DataFrame :
import pandas as pd
def tableaux_vers_dataframes(markdown: str) -> list[pd.DataFrame]:
"""Convertit les tableaux Markdown en DataFrames pandas."""
tableaux = extraire_tableaux_markdown(markdown)
dataframes = []
for tableau in tableaux:
if len(tableau) < 2:
continue
en_tetes = tableau[0]
donnees = tableau[1:]
df = pd.DataFrame(donnees, columns=en_tetes)
dataframes.append(df)
return dataframes
# Utilisation
for page in ocr_response.pages:
dfs = tableaux_vers_dataframes(page.markdown)
for df in dfs:
print(df.to_string())
print()
Gestion des tableaux complexes
Pour les tableaux avec cellules fusionnées ou mises en page irrégulières, préférez le format HTML et utilisez BeautifulSoup :
from bs4 import BeautifulSoup
import pandas as pd
ocr_response = client.ocr.process(
model="mistral-ocr-latest",
document={
"type": "document_url",
"document_url": "https://exemple.com/rapport-complexe.pdf"
},
table_format="html"
)
for page in ocr_response.pages:
soup = BeautifulSoup(page.markdown, "html.parser")
tables = soup.find_all("table")
for table in tables:
df = pd.read_html(str(table))[0]
print(df)
Points clés à retenir
- Le paramètre
table_formatcontrôle le rendu des tableaux (null, markdown, html) - Le format Markdown convient à la majorité des cas d’usage
- Le format HTML préserve les cellules fusionnées et la mise en forme avancée
- Les tableaux extraits peuvent être convertis en DataFrames pandas pour l’analyse
- OCR 3 reconstruit fidèlement la structure tabulaire, même sur des mises en page complexes