Critical fix for Amazon price detection - AI was returning price=null with 0.0 confidence
even though stock detection worked (1.0 confidence).
**Root Cause:**
- Amazon injects prices via JavaScript into hidden .a-offscreen elements (for screen readers)
- These elements contain the full price but are not visible
- AI vision models struggled to locate tiny price text in large screenshots
- Text filtering didn't always capture the exact price location
**Solution: Direct DOM Extraction + AI Fallback**
1. **New Method: _extract_amazon_price()** (browserless_service.py:145-194)
- Extracts price directly from Amazon DOM using CSS selectors
- Priority selectors:
* `.a-price .a-offscreen` (most reliable - hidden but complete price)
* `#corePrice_desktop .a-price .a-offscreen`
* `#corePriceDisplay_desktop_feature_div .a-price .a-offscreen`
* `#priceblock_ourprice` (older layouts)
* Fallback: `span.a-price-whole` + `span.a-price-fraction`
- Handles hidden elements (.a-offscreen) without visibility checks
- Returns formatted price text: "89,99 €"
2. **Price Injection into Context** (browserless_service.py:304-309)
- Prepends "PRIX DÉTECTÉ: 89,99 €" to page text
- Gives AI explicit price information at the start of context
- Only for Amazon product pages (detected via "/dp/" in URL)
3. **Improved AI Prompt** (ai_schema.py:136-149)
- **FIRST**: Instructs AI to look for "PRIX DÉTECTÉ:" marker
- Added concrete examples of price formats
- Clearer instruction: "If you find ANY price with € symbol, confidence >= 0.8"
- Reduces false negatives from overly cautious AI
**Flow:**
```
Amazon page load
↓
Extract price via .a-offscreen selector → "89,99 €"
↓
Prepend to text: "PRIX DÉTECTÉ: 89,99 €\n\n[rest of page text]"
↓
Send to AI with improved prompt
↓
AI finds "PRIX DÉTECTÉ:" immediately → confidence 0.8-1.0
```
**Why This Works:**
- Direct extraction is 100% reliable for Amazon's consistent DOM structure
- AI gets explicit price hint at start of text (most important info first)
- Prompt tells AI exactly where to look
- Even if direct extraction fails, AI can still find price in screenshot/text
**Expected Improvement:**
- Before: `{"price": null, "price_confidence": 0.0}`
- After: `{"price": 89.99, "price_confidence": 0.95}`
Tested with Amazon.fr MSI Mag product page.
Critical improvements to AI price extraction for better accuracy:
**1. Extract Visible Text Instead of HTML** (browserless_service.py)
- Changed from `page.content()` (raw HTML) to `page.inner_text('body')`
- Now captures text as rendered by JavaScript, not HTML source
- Amazon and other sites inject prices via JavaScript - HTML source doesn't contain them
- Includes proper fallback to HTML if inner_text fails
**2. Amazon-Specific Price Detection** (browserless_service.py)
- Wait for Amazon price elements to load before screenshot:
- `.a-price .a-offscreen` (main price)
- `#corePriceDisplay_desktop_feature_div` (price section)
- `#corePrice_desktop` (alternative container)
- `.a-price-whole` (price number)
- Prevents screenshots before dynamic prices are rendered
**3. Focused Amazon Screenshots** (browserless_service.py)
- Problem: Full-page Amazon screenshots are huge (multiple screens tall)
- When resized to 2048px, price text becomes tiny and unreadable
- Solution: Take focused screenshot of product container only:
- Try `#dp-container`, `#ppd`, or `#centerCol` (product areas)
- Falls back to viewport screenshot (better than full-page)
- Other sites still use full-page screenshots
**4. Enhanced Debug Logging** (ai_service.py)
- Log cleaned text preview (first 500 chars) to verify content
- Log prompt preview to debug AI instructions
- Warning when no page_text provided
These changes address the root causes of AI returning:
- price: null, confidence: 0.0-0.1 (too low to update DB)
Expected improvement:
- Visible text contains actual rendered prices
- Smaller, focused screenshots = better AI recognition
- Confidence scores should reach > 0.5 threshold
Three critical fixes to resolve AI extraction returning null prices with 0.0 confidence:
1. **Add French price/stock keywords** (app/utils/text.py)
- Added € symbol and French price patterns (12,99 €, 1 234,56 €)
- Added French keywords: prix, coût, promotion, réduction
- Added French stock keywords: ajouter au panier, en stock, rupture, épuisé
- Previously only detected $ and English keywords
2. **Enable full-page screenshots** (app/services/browserless_service.py)
- Changed full_page=False to full_page=True
- Now captures entire page instead of viewport-only
- Prevents missing prices located below the fold
3. **Increase image resolution** (app/utils/image.py)
- Increased MAX_IMAGE_SIZE from 1024px to 2048px
- Preserves fine details in price text for better AI recognition
- Improves readability on dense product pages
These changes fix the issue where AI models returned:
{"price": null, "price_confidence": 0.0, "in_stock": null, "in_stock_confidence": 0.0}
Tested with Amazon.fr product monitoring.