不用再费劲去查源代码啦
正常是从源代码查找:
rel="icon"
rel="shortcut icon"
rel="apple-touch-icon"
等字符,但是有些网站可能并非是写入meta标签中而是动态生成,搜索不到的;
当无favicon图标地址时候直接用此方法就方便啦;
博客友链,导航站,这些用上 省事很多;
调用:
https://favicon.splitbee.io/?url=网页地址
例如:
https://favicon.splitbee.io/?url=https://www.dalao.net/
https://favicon.splitbee.io/?url=https://www.ximi.me/
tino https://ink.tino.im/api/content/links/fetch-metadata?url=dalao.net 支持
不错,能开源嚒
brynn 不错,能开源不
用ai写了一个:
例:
https://i.ximi.me/logo.php?url=google.com
代码:
<?php /** * 仿 Splitbee Favicon 获取器 * 用法: favicon.php?url=https://www.baidu.com */ // 1. 获取并清理传入的 URL $target_url = isset($_GET['url']) ? trim($_GET['url']) : ''; if (empty($target_url)) { header("HTTP/1.1 400 Bad Request"); echo "Missing 'url' parameter."; exit; } // 确保 URL 带有协议头 if (!preg_match("~^https?://~i", $target_url)) { $target_url = "http://" . $target_url; } // 解析出基础域名和 Scheme(用于后续拼接相对路径) $parsed_url = parse_url($target_url); if (!$parsed_url || !isset($parsed_url['host'])) { header("HTTP/1.1 400 Bad Request"); echo "Invalid URL."; exit; } $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host']; // 2. 初始化 cURL 用于请求 function fetch_content($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向 curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置超时 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略SSL证书错误 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return [$data, $http_code]; } $favicon_url = null; // 3. 步骤一:尝试抓取网页 HTML 并解析 list($html, $code) = fetch_content($target_url); if ($code == 200 && !empty($html)) { // 使用 DOMDocument 解析 HTML,比正则更稳定 $dom = new DOMDocument(); // 禁用错误报错(防止 HTML 结构不规范弹出警告) libxml_use_internal_errors(true); $dom->loadHTML($html); libxml_clear_errors(); $links = $dom->getElementsByTagName('link'); foreach ($links as $link) { $rel = strtolower($link->getAttribute('rel')); // 匹配常见的 icon 关键词 if (in_array($rel, ['icon', 'shortcut icon', 'apple-touch-icon'])) { $href = $link->getAttribute('href'); if (!empty($href)) { $favicon_url = $href; break; // 找到第一个就跳出 } } } } // 4. 步骤二:如果 HTML 中没找到,或者请求失败,尝试降级读取根目录下的 favicon.ico if (empty($favicon_url)) { $favicon_url = $base_url . '/favicon.ico'; } else { // 5. 步骤三:补全相对路径 if (substr($favicon_url, 0, 2) === '//') { $favicon_url = $parsed_url['scheme'] . ':' . $favicon_url; } elseif (substr($favicon_url, 0, 1) === '/') { $favicon_url = $base_url . $favicon_url; } elseif (!preg_match("~^https?://~i", $favicon_url)) { // 针对类似 "images/favicon.ico" 的相对路径 $favicon_url = rtrim($target_url, '/') . '/' . ltrim($favicon_url, '/'); } } // 6. 步骤四:请求真实的图标并输出 list($icon_data, $icon_code) = fetch_content($favicon_url); if ($icon_code == 200 && !empty($icon_data)) { // 简单判断并设置图片响应头(也可以根据实际后缀或 mime 动态设置) if (strpos($favicon_url, '.png') !== false) { header('Content-Type: image/png'); } elseif (strpos($favicon_url, '.svg') !== false) { header('Content-Type: image/svg+xml'); } else { header('Content-Type: image/x-icon'); } echo $icon_data; } else { // 如果连默认的也获取不到,可以返回一个你本地准备好的兜底透明图或默认图 header('Content-Type: image/png'); // 这里输出一个 1x1 的透明 PNG 或者是本地默认图标 echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='); }
你这个与我用ai写的这个算法上好像有点点区别,可能是获取优先级不一样;
获取的图标不一样;
https://i.ximi.me/logo.php?url=www.ximi.me
https://ink.tino.im/api/content/links/fetch-metadata?url=www.ximi.me
佳茗 记得之前坛里也有佬整过一个 favicon.im
功能不错,但是广告太多太离谱了
tino 可以让ai转写成php的 @Slf4j public class LinkUtils { private static final int TIMEOUT = 5000; private static ...
根据你提供的代码转化好了
logo:
json:
https://i.ximi.me/json.php?url=www.ximi.me
代码如下:
<?php // 1. 设置响应头为 JSON 格式 header('Content-Type: application/json; charset=utf-8'); // 2. 获取并清理 URL $target_url = isset($_GET['url']) ? trim($_GET['url']) : ''; if (empty($target_url)) { echo json_encode([ "status" => 400, "message" => "Bad Request", "devMessage" => "Missing 'url' parameter.", "data" => null ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } // 补全协议头 if (!preg_match("~^https?://~i", $target_url)) { $target_url = "https://" . $target_url; } // 解析域名基础路径 $parsed_url = parse_url($target_url); if (!$parsed_url || !isset($parsed_url['host'])) { echo json_encode([ "status" => 400, "message" => "Bad Request", "devMessage" => "Invalid URL.", "data" => null ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $base_url = $parsed_url['scheme'] . '://' . $parsed_url['host']; // 3. 构造纯原生的请求环境(模拟浏览器) $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\r\n", 'timeout' => 5, 'follow_location' => 1, 'ignore_errors' => true ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ] ]); // 4. 抓取网页 HTML $html = @file_get_contents($target_url, false, $context); // 初始化返回的 Data 结构 (对应你的 LinkInfoDTO) $data = [ "url" => $target_url, "name" => "", "logo" => "", "description" => "", "charset" => "UTF-8" // 默认给 UTF-8 ]; if ($html) { // 5. 尝试从 Response Header 中或 HTML 中提取 Charset // 这里简单通过正则从 HTML 匹配 charset if (preg_match('/<meta[^>]+charset=["\']?([\w-]+)/i', $html, $matches)) { $data['charset'] = strtoupper($matches[1]); } // 6. 提取网站标题 Name (优先找 <title>,找不到找 og:title) if (preg_match('/<title>(.*?)<\/title>/is', $html, $matches)) { $data['name'] = trim($matches[1]); } if (empty($data['name'])) { if (preg_match('/<meta[^>]+(?:property|name)=["\'](?:og|twitter):title["\'][^>]+content=["\']([^"\']+)["\']/i', $html, $matches)) { $data['name'] = trim($matches[1]); } } // 7. 用正则匹配 <link> 标签中的 icon / logo $favicon_url = ''; if (preg_match('/<link[^>]+rel=["\'](?:shortcut )?icon["\'][^>]+href=["\']([^"\']+)["\']/i', $html, $matches)) { $favicon_url = $matches[1]; } else { // 尝试匹配苹果设备高清图标 if (preg_match('/<link[^>]+rel=["\']apple-touch-icon[^"\']*["\'][^>]+href=["\']([^"\']+)["\']/i', $html, $matches)) { $favicon_url = $matches[1]; } } // 如果 HTML 没找到 logo,尝试找 og:image if (empty($favicon_url)) { if (preg_match('/<meta[^>]+(?:property|name)=["\'](?:og|twitter):image["\'][^>]+content=["\']([^"\']+)["\']/i', $html, $matches)) { $favicon_url = $matches[1]; } } // 8. 路径补全逻辑 if (empty($favicon_url)) { $favicon_url = $base_url . '/favicon.ico'; } else { if (substr($favicon_url, 0, 2) === '//') { $favicon_url = $parsed_url['scheme'] . ':' . $favicon_url; } elseif (substr($favicon_url, 0, 1) === '/') { $favicon_url = $base_url . $favicon_url; } elseif (!preg_match("~^https?://~i", $favicon_url)) { $favicon_url = rtrim($target_url, '/') . '/' . ltrim($favicon_url, '/'); } } $data['logo'] = $favicon_url; // 9. 提取网站描述 Description if (preg_match('/<meta[^>]+(?:name|property)=["\'](?:description|og:description|twitter:description)["\'][^>]+content=["\']([^"\']+)["\']/i', $html, $matches)) { $data['description'] = trim($matches[1]); } } // 10. 组装最终的目标 JSON 格式 $result = [ "status" => 200, "message" => "OK", "devMessage" => null, "data" => $data ]; // 输出 JSON echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
cjwlove 希米出品,必属精品。 期待开源
代码就在楼上