mirror of
https://github.com/R0m1k3/Priceflow.git
synced 2026-10-12 09:49:39 +02:00
Merge pull request #120 from R0m1k3/claude/add-product-monitoring-01DyNDGnKBX4fHNSjAkwVckd
feat: Extract visible text and optimize Amazon price detection
This commit is contained in:
2 files changed
+69
-4
No files matched your search
@@ -343,8 +343,14 @@ class AIService:
|
||||
if len(cleaned_text) > MAX_TEXT_LENGTH:
|
||||
cleaned_text = cleaned_text[:MAX_TEXT_LENGTH] + "...(truncated)"
|
||||
logger.info(f"Added text context (original: {len(page_text)}, cleaned: {len(cleaned_text)})")
|
||||
# Debug: Log first 500 chars of cleaned text to see what AI receives
|
||||
logger.debug(f"Cleaned text preview: {cleaned_text[:500]!r}")
|
||||
else:
|
||||
logger.warning("No page_text provided - AI will only use screenshot")
|
||||
|
||||
prompt = get_extraction_prompt(cleaned_text if cleaned_text else None)
|
||||
# Debug: Log prompt preview
|
||||
logger.debug(f"Prompt preview (first 300 chars): {prompt[:300]!r}")
|
||||
|
||||
# Call LLM
|
||||
response_text = await cls.call_llm(prompt, data_url, config)
|
||||
|
||||
@@ -215,13 +215,39 @@ class BrowserlessService:
|
||||
except Exception:
|
||||
logger.warning(f"Wait selector {wait_selector} timed out")
|
||||
|
||||
# For Amazon product pages, wait for price to load
|
||||
if "amazon" in url.lower() and "/dp/" in url:
|
||||
amazon_price_selectors = [
|
||||
".a-price .a-offscreen", # Main price element
|
||||
"#corePriceDisplay_desktop_feature_div", # Price section
|
||||
"#corePrice_desktop", # Alternative price container
|
||||
".a-price-whole", # Price number
|
||||
]
|
||||
for selector in amazon_price_selectors:
|
||||
try:
|
||||
await page.wait_for_selector(selector, timeout=5000, state="visible")
|
||||
logger.info(f"Amazon price element found: {selector}")
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
else:
|
||||
logger.warning("No Amazon price selector found, proceeding anyway")
|
||||
|
||||
# Wait for network idle to ensure dynamic content loads
|
||||
try:
|
||||
await page.wait_for_load_state("networkidle", timeout=5000)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
content = await page.content()
|
||||
# Extract visible text instead of raw HTML
|
||||
# This gets the text as rendered by JavaScript, not the HTML source
|
||||
try:
|
||||
content = await page.inner_text('body')
|
||||
logger.info(f"Extracted {len(content)} chars of visible text from page")
|
||||
except Exception as e:
|
||||
# Fallback to HTML content if inner_text fails
|
||||
logger.warning(f"Failed to extract inner_text, falling back to HTML: {e}")
|
||||
content = await page.content()
|
||||
|
||||
# Take screenshot if needed for AI analysis
|
||||
screenshot_path = ""
|
||||
@@ -239,9 +265,42 @@ class BrowserlessService:
|
||||
filename = f"{safe_name}_{timestamp}.jpg"
|
||||
screenshot_path = f"{screenshots_dir}/{filename}"
|
||||
|
||||
# Use full_page=True to capture entire page, not just viewport
|
||||
await page.screenshot(path=screenshot_path, full_page=True, quality=80, type="jpeg")
|
||||
logger.info(f"Screenshot saved to {screenshot_path}")
|
||||
# For Amazon, take focused screenshot of product info area
|
||||
# Full-page screenshots of Amazon are too large and price becomes tiny when resized
|
||||
is_amazon = "amazon" in url.lower() and "/dp/" in url
|
||||
|
||||
if is_amazon:
|
||||
# Try to screenshot just the main product area containing price
|
||||
try:
|
||||
# Look for main product container
|
||||
product_selectors = [
|
||||
"#dp-container", # Main product container
|
||||
"#ppd", # Product page data
|
||||
"#centerCol", # Center column with price
|
||||
]
|
||||
screenshot_taken = False
|
||||
for selector in product_selectors:
|
||||
try:
|
||||
element = page.locator(selector).first
|
||||
if await element.is_visible():
|
||||
await element.screenshot(path=screenshot_path, quality=85, type="jpeg")
|
||||
logger.info(f"Amazon focused screenshot saved using {selector}")
|
||||
screenshot_taken = True
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not screenshot_taken:
|
||||
# Fallback to viewport screenshot (better than full-page for Amazon)
|
||||
await page.screenshot(path=screenshot_path, full_page=False, quality=80, type="jpeg")
|
||||
logger.info("Amazon viewport screenshot saved (fallback)")
|
||||
except Exception as e:
|
||||
logger.warning(f"Amazon focused screenshot failed: {e}, using viewport")
|
||||
await page.screenshot(path=screenshot_path, full_page=False, quality=80, type="jpeg")
|
||||
else:
|
||||
# For non-Amazon sites, use full_page to capture entire page
|
||||
await page.screenshot(path=screenshot_path, full_page=True, quality=80, type="jpeg")
|
||||
logger.info(f"Full-page screenshot saved to {screenshot_path}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to take screenshot: {e}")
|
||||
|
||||
|
||||
Reference in new issue
Block a user