diff --git a/Dockers/puppeteer-api/main.py b/Dockers/puppeteer-api/main.py index 8a322fa..23ec808 100644 --- a/Dockers/puppeteer-api/main.py +++ b/Dockers/puppeteer-api/main.py @@ -305,8 +305,73 @@ async def extract_seo(url: str, x_api_key: Optional[str] = Header(None)): try: print(f"Extracting SEO from: {decoded_url}") - # Use the safe_browser_operation function to perform the browser operation - result = await safe_browser_operation(decoded_url, asyncio.run) + # Define the operation to perform with the browser + async def seo_operation(page): + try: + response = await page.goto(decoded_url, waitUntil='networkidle2', timeout=30000) + + # Extract SEO information + seo_data = await page.evaluate('''() => { + const data = { + title: document.title || '', + description: '', + canonical: '', + h1: [], + h2: [], + images: 0, + links: 0 + }; + + // Get meta description + const metaDescription = document.querySelector('meta[name="description"]'); + if (metaDescription) { + data.description = metaDescription.getAttribute('content') || ''; + } + + // Get canonical link + const canonicalLink = document.querySelector('link[rel="canonical"]'); + if (canonicalLink) { + data.canonical = canonicalLink.getAttribute('href') || ''; + } + + // Get h1 tags + document.querySelectorAll('h1').forEach(h1 => { + const text = h1.innerText.trim(); + if (text) data.h1.push(text); + }); + + // Get h2 tags + document.querySelectorAll('h2').forEach(h2 => { + const text = h2.innerText.trim(); + if (text) data.h2.push(text); + }); + + // Count images + data.images = document.querySelectorAll('img').length; + + // Count links + data.links = document.querySelectorAll('a').length; + + return data; + }''') + + result = { + "status": "success", + "url": decoded_url, + "seo": seo_data + } + + return result + + except Exception as e: + print(f"Error during SEO extraction: {e}") + return {"status": "error", "url": decoded_url, "error": str(e)} + + # Perform the operation + result = await safe_browser_operation(decoded_url, seo_operation) + + # Save to cache + save_to_cache(decoded_url, "seo", result) return result @@ -331,8 +396,63 @@ async def extract_meta_tags(url: str, x_api_key: Optional[str] = Header(None)): try: print(f"Extracting meta tags from: {decoded_url}") - # Use the safe_browser_operation function to perform the browser operation - result = await safe_browser_operation(decoded_url, asyncio.run) + # Define the operation to perform with the browser + async def meta_operation(page): + try: + response = await page.goto(decoded_url, waitUntil='networkidle2', timeout=30000) + + # Extract all meta tags + meta_tags = await page.evaluate('''() => { + const metas = Array.from(document.querySelectorAll('meta')); + return metas.map(meta => { + const attributes = {}; + Array.from(meta.attributes).forEach(attr => { + attributes[attr.name] = attr.value; + }); + return attributes; + }); + }''') + + # Extract Open Graph tags + og_tags = await page.evaluate('''() => { + const ogTags = {}; + document.querySelectorAll('meta[property^="og:"]').forEach(tag => { + const property = tag.getAttribute('property'); + ogTags[property] = tag.getAttribute('content'); + }); + return ogTags; + }''') + + # Extract Twitter card tags + twitter_tags = await page.evaluate('''() => { + const twitterTags = {}; + document.querySelectorAll('meta[name^="twitter:"]').forEach(tag => { + const name = tag.getAttribute('name'); + twitterTags[name] = tag.getAttribute('content'); + }); + return twitterTags; + }''') + + result = { + "status": "success", + "url": decoded_url, + "meta_tags": meta_tags, + "open_graph": og_tags, + "twitter_card": twitter_tags, + "title": await page.title() + } + + return result + + except Exception as e: + print(f"Error during meta tag extraction: {e}") + return {"status": "error", "url": decoded_url, "error": str(e)} + + # Perform the operation + result = await safe_browser_operation(decoded_url, meta_operation) + + # Save to cache + save_to_cache(decoded_url, "meta", result) return result