This commit is contained in:
@@ -305,8 +305,73 @@ async def extract_seo(url: str, x_api_key: Optional[str] = Header(None)):
|
|||||||
try:
|
try:
|
||||||
print(f"Extracting SEO from: {decoded_url}")
|
print(f"Extracting SEO from: {decoded_url}")
|
||||||
|
|
||||||
# Use the safe_browser_operation function to perform the browser operation
|
# Define the operation to perform with the browser
|
||||||
result = await safe_browser_operation(decoded_url, asyncio.run)
|
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
|
return result
|
||||||
|
|
||||||
@@ -331,8 +396,63 @@ async def extract_meta_tags(url: str, x_api_key: Optional[str] = Header(None)):
|
|||||||
try:
|
try:
|
||||||
print(f"Extracting meta tags from: {decoded_url}")
|
print(f"Extracting meta tags from: {decoded_url}")
|
||||||
|
|
||||||
# Use the safe_browser_operation function to perform the browser operation
|
# Define the operation to perform with the browser
|
||||||
result = await safe_browser_operation(decoded_url, asyncio.run)
|
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
|
return result
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user