feat: fix parsing

This commit is contained in:
2026-01-18 10:33:09 +01:00
parent 6bad5fbaf9
commit ee1db93298
4 changed files with 210 additions and 40 deletions

View File

@@ -6,6 +6,78 @@ from ..utils.dates import parse_french_date
from ..utils.amounts import extract_amounts_from_line
def _preprocess_locataires_text(text: str) -> str:
"""Prétraite le texte pour fusionner les sections sur plusieurs pages.
Supprime les éléments répétés sur chaque page pour permettre une extraction
continue des locataires dont les données s'étalent sur plusieurs pages.
Args:
text: Texte brut du PDF
Returns:
Texte nettoyé avec une seule section SITUATION DES LOCATAIRES
"""
lines = text.split("\n")
cleaned_lines = []
first_situation_found = False
in_situation_section = False
# Patterns à ignorer (en-têtes répétés sur chaque page)
skip_patterns = [
r"^\s*ROSIER-MODICA\s*$",
r"^\s*9 rue Juliette Récamier\s*$",
r"^\s*69455 Lyon Cedex 06\s*$",
r"^\s*S\.C\.I\.\s*PLESNA\s*$",
r"^\s*Immeuble\s*:\s*\d+\s*$",
r"^\s*\d+\s*RUE\s+", # Adresse immeuble
r"^\s*69\d{3}\s+LYON\s*$", # Code postal + ville
r"^\s*Lyon le \d{2}/\d{2}/\d{4}\s*$", # Date
r"^\s*Powered by ICS\s*$",
r"^\s*\d+\s*/\s*\d+\s*$", # Numéro de page (ex: 2/5)
r"^\s*Capital de", # Pied de page
r"^\s*Garantie de", # Pied de page
]
# Pattern pour l'en-tête de colonnes
header_pattern = r"^\s*Locataires\s+Période\s+Loyers"
for line in lines:
stripped = line.strip()
# Ignorer les lignes vides
if not stripped:
cleaned_lines.append(line)
continue
# Vérifier si c'est un pattern à ignorer
should_skip = False
for pattern in skip_patterns:
if re.match(pattern, stripped, re.IGNORECASE):
should_skip = True
break
if should_skip:
continue
# Gérer SITUATION DES LOCATAIRES
if "SITUATION DES LOCATAIRES" in stripped:
if not first_situation_found:
first_situation_found = True
in_situation_section = True
cleaned_lines.append(line)
# Ignorer les occurrences suivantes
continue
# Ignorer les en-têtes de colonnes répétés
if re.match(header_pattern, stripped):
continue
cleaned_lines.append(line)
return "\n".join(cleaned_lines)
def extract_situation_locataires(text: str) -> list[dict]:
"""Extrait la situation des locataires.
@@ -21,6 +93,9 @@ def extract_situation_locataires(text: str) -> list[dict]:
"""
situations: list[dict] = []
# Prétraiter le texte pour gérer les lots sur plusieurs pages
text = _preprocess_locataires_text(text)
# Trouver toutes les sections "SITUATION DES LOCATAIRES"
sections = text.split("SITUATION DES LOCATAIRES")