fix: Normalize alternative French price format (digits€cents without separator)

**Problem:**
L'Incroyable product showing "3€99" was detected as 399.00 EUR instead of 3.99 EUR.
URL: https://www.lincroyable.fr/p95361-porte-magique-lutin/

**Root Cause:**
Previous normalization only handled "3,99 €" (with comma separator).
Some French sites use alternative format: "3€99" (euro symbol as separator).

Existing regex:
```python
re.sub(r'(\d+),(\d{2})\s*€', r'\1.\2 €', content)  # Only matches "3,99 €"
```

Missed format:
```
"3€99"  → No match → AI sees "399" → Returns 399.00
```

**Solution: Add Pattern for Euro-as-Separator Format**

1. **Text Normalization** (browserless_service.py:408-411)
   ```python
   # NEW Pattern 1: digits€XX → digits.XX €
   content = re.sub(r'(\d+)€(\d{2})\b', r'\1.\2 €', content)
   # "3€99" → "3.99 €"
   # "19€50" → "19.50 €"

   # Pattern 2: digits,XX € → digits.XX € (existing)
   content = re.sub(r'(\d+),(\d{2})\s*€', r'\1.\2 €', content)
   # "3,99 €" → "3.99 €"
   ```

2. **Extracted Price Normalization** (browserless_service.py:438-441)
   - Same patterns applied to directly extracted prices
   - Ensures consistency regardless of extraction method

**Regex Details:**
- `(\d+)€(\d{2})\b` matches:
  * `\d+` = one or more digits (euros)
  * `€` = euro symbol as separator
  * `(\d{2})` = exactly 2 digits (cents)
  * `\b` = word boundary (prevents matching "10€999")
- Replacement: `\1.\2 €` = "digits.cents €"

**Supported Formats After Fix:**
```
"3,99 €"   → "3.99 €"  ✓ (existing)
"3€99"     → "3.99 €"  ✓ (NEW)
"19,50 €"  → "19.50 €" ✓ (existing)
"19€50"    → "19.50 €" ✓ (NEW)
"1 234,56" → "1234.56" ✓ (existing)
```

**Flow:**
```
Page text: "Porte Magique 3€99"
  ↓
Normalization: "Porte Magique 3.99 €"
  ↓
Extracted: "3€99" → Normalized: "3.99 €"
  ↓
Sent to AI: "PRIX DÉTECTÉ: 3.99 €\n\nPorte Magique 3.99 €"
  ↓
AI sees: "3.99" (NOT "399")
  ↓
Returns: 3.99 ✓
```

**Expected Results:**
- Before: "3€99" → AI returns 399.00 ❌
- After: "3€99" → Normalized to "3.99 €" → AI returns 3.99 ✅

Fixes L'Incroyable and any other sites using euro-as-separator format.
Complements existing comma-separator normalization.
This commit is contained in:
Claude committed 2025-11-29 23:56:39 +00:00
1 parent 1c763143ca
commit 66d9046de2
1 file changed
+8 -5
+8 -5
View File
@@ -403,9 +403,11 @@ class BrowserlessService:
content = await page.inner_text('body')
logger.info(f"Extracted {len(content)} chars of visible text from page")
# Normalize French prices to English format for AI (3,99 € → 3.99 €)
# Normalize French prices to English format for AI
import re
# Replace comma with dot in price patterns: digits,XX € → digits.XX €
# Pattern 1: digits€XX → digits.XX € (e.g., "3€99" → "3.99 €")
content = re.sub(r'(\d+)€(\d{2})\b', r'\1.\2 €', content)
# Pattern 2: digits,XX € → digits.XX € (e.g., "3,99 €" → "3.99 €")
content = re.sub(r'(\d+),(\d{2})\s*€', r'\1.\2 €', content)
# Remove spaces in thousands: 1 234.56 → 1234.56
content = re.sub(r'(\d+)\s(\d{3})', r'\1\2', content)
@@ -432,11 +434,12 @@ class BrowserlessService:
# Prepend extracted price to content if found
if extracted_price:
# Convert French format to English for AI (3,99 → 3.99)
# Convert French format to English for AI
import re
normalized_price = extracted_price
# Replace comma with dot for decimal separator (French to English)
# Pattern: digits, comma, 2 digits → digits, dot, 2 digits
# Pattern 1: digits€digits → digits.digits € (e.g., "3€99" → "3.99 €")
normalized_price = re.sub(r'(\d+)€(\d{2})', r'\1.\2 €', normalized_price)
# Pattern 2: digits,digits → digits.digits (e.g., "3,99" → "3.99")
normalized_price = re.sub(r'(\d+),(\d{2})', r'\1.\2', normalized_price)
# Remove spaces in thousands separators if any (1 234,56 → 1234.56)
normalized_price = normalized_price.replace(' ', '')