$max_urls) {
echo json_encode(['error' => "Maximum {$max_urls} URLs allowed per request."]);
exit;
}
$results = [];
foreach ($urls as $u) {
$orig = $u;
// basic url normalization
if (!preg_match('~^https?://~', $u)) {
$u = 'http://' . $u;
}
// validate
if (!filter_var($u, FILTER_VALIDATE_URL)) {
$results[] = [
'url' => $orig,
'error' => 'Invalid URL'
];
continue;
}
// fetch HTML via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $u);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 12);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (SEO Meta Tool)");
// optional: accept gzip
curl_setopt($ch, CURLOPT_ENCODING, '');
$html = curl_exec($ch);
$curl_err = curl_error($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($html === false || !$html || $http_code >= 400) {
$results[] = [
'url' => $orig,
'error' => $curl_err ?: "Could not fetch (HTTP {$http_code})"
];
continue;
}
// parse DOM
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML($html);
libxml_clear_errors();
// title
$title = "No title found";
$tn = $doc->getElementsByTagName("title");
if ($tn->length > 0) $title = trim($tn->item(0)->nodeValue);
// meta tags
$description = "No description found";
$keywords = "No keywords found";
$metaTags = $doc->getElementsByTagName("meta");
foreach ($metaTags as $meta) {
$name = strtolower($meta->getAttribute("name"));
$prop = strtolower($meta->getAttribute("property"));
$content = trim($meta->getAttribute("content"));
if (($name === "description" || $prop === "og:description") && $content !== '') {
$description = $content;
}
if ($name === "keywords" && $content !== '') {
$keywords = $content;
}
}
// Keyword Count (from keywords meta if exists; otherwise try extract from description + title)
$source_for_kw = ($keywords !== "No keywords found" && strlen($keywords) > 2) ? $keywords : ($title . ' ' . $description);
// normalize: remove punctuation except spaces, lowercase
$norm = mb_strtolower($source_for_kw, 'UTF-8');
$norm = preg_replace('/[^\p{L}\p{N}\s,]+/u', ' ', $norm); // keep letters/numbers/spaces/commas
// split by comma or whitespace
$parts = preg_split('/[\s,]+/u', $norm);
$counts = [];
foreach ($parts as $p) {
$p = trim($p);
if (mb_strlen($p, 'UTF-8') <= 1) continue;
if (!isset($counts[$p])) $counts[$p] = 0;
$counts[$p]++;
}
arsort($counts);
// Hashtag suggestions (top 10)
$hashtags = [];
$i = 0;
foreach ($counts as $k => $v) {
if ($i >= 10) break;
// convert spaces to nothing, remove non-alnum (keep unicode letters & numbers)
$ht = preg_replace('/[^\p{L}\p{N}]+/u', '', $k);
if ($ht === '') continue;
$hashtags[] = '#' . $ht;
$i++;
}
$results[] = [
'url' => $orig,
'fetched_url' => $u,
'title' => $title,
'description' => $description,
'keywords_meta' => $keywords,
'keyword_count' => $counts,
'hashtags' => $hashtags
];
}
echo json_encode(['results' => $results], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
}
?>
SEO Meta Tool — একাধিক লিঙ্ক থেকে Title/Meta/Hashtags
SEO Meta Extractor (Single file)
একাধিক URL দিন (প্রতিটি নতুন লাইনে)। সর্বোচ্চ 20 টি URL প্রতি অনুরোধে।
ফ্রিকোয়েন্টly, কিছু সাইট robots বা ক্যাপচা/ব্লকিং থাকবে — তাহলে ডাটা আসবে না।