独立开发日记 01:鞭策AI,几个小时搞定获取网站图标项目
有一个用户在群里面反馈,说我的网站书签获取的图标,有获取ico展示失败的,显示的都是默认的logo图还有图片裂开的情况。 爱壹帆在线

这个获取站点图标项目是我2年前网上找的一个开源的PHP项目,然后作者也非常久没维护了,我拉下来改改,直接就是部署一波,有一些小问题,不是很影响,后面想着再优化优化,大家懂的一般说后面再做的事情......。期间也是优化了几次,因为不 会PHP没敢大改动,都是一些站点小兼容。现在有AI了,有啥会不会的,直接鞭策AI不就好了吗 🤔 !!!也是好起来了,对PHP一点不会,使用AI花了几个小时深度优化了一波。项目原核心逻辑根据网站的url 获取网页的源码,然后使用正则获取源码里面的可能是icon的link标签,最后获取link标签的href路径 ,存为文件,缓存30天。原逻辑是从html中获取 link标签 约炮
if (@preg_match('/((<link[^>]+rel=.(icon|shortcut icon|alternate icon|apple-touch-icon)[^>]+>))/i', $html['data'], $match_tag)) {
ps:有的朋友可能是直接暴力获取 www.baidu.com/favicon.ico,但是有的网站根本没有这个 小宝影院 楼凤信息
使用正则获取link标签并不是很规范 rel可能在href后面 有点在前面 还有引号的问题,导致无法匹配
目前遇到的一些ico的格式有 各种各样的 通过url/favicon.ico 只能获取小部分的icon问题
Kimi的 icon是个cdn图地址,还不是一个站点url下的 xxxvideo 电影小宝影院 xxxxx 爱壹帆免费版 寻芳网
<link rel="shortcut icon" href=//statics.moonshot.cn/kimi-web-seo/favicon.ico>
<link rel="icon" href="//lf-flow-web-cdn.doubao.com/obj/flow-doubao/doubao/web/logo-icon.png">金山文档的 base64和远程cdn图标 小宝影院
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAACH1BMVEUAAAA9kP8mpv9Fv/8QT94TXeQAfv8trP0xr/0VUdoAcv8LgPs1sf4AgP4QUuURTuEVl/ksq/wAg/84tf4NUt80sf0bnPsPUuAAYfsAgP4UTtYAY/8GXPQRkv1Jxv8AZP86tv9Bvv9Gv/9Atv8KiPUOVesAZ+wbS8wUl/kjo/sAYv8PVekjovxBu/8AY/8trPxCu/8AW/AAcvAxsP0npvsYTdElo/oQT9o+uP8AYv8KVOIHdugAYfwAfPwbfe49uf4XmfkcdOopo/oAYv86tf4AYf8TT9cZaeYVTdUJVOUcnvsAYv8Agv9Iwv8AYv9Jwf8bSs0gofoAY/8Ag/9Gv/8en/oAYf9Fv/8AWuQZS80AdO5BvP8AYv9DvP8Umfo9uv8LVOUAgf8amfk/uf8AY/8Ag/8Ahf8TUdgVT9UNWOknov8trPwxr/wmpvspqfs1sv0io/s5tf0AgP8bnfoMV+4AYPoAYv8AYf4AYfwAe/sen/oAd/gAXvYAff0LW/MLWfEOUN0PT9oSTtZAu/49uP0qqfweoPoXmvkAdPUAXPIAcfEKUuIWTNIXS88KXPYAWusOVeoPVOkPUuYQUeQQT+IMUeAUTdMZSs09uP4Aa+kAWOgAaeQIVOQIU+QAV+MRTd8STd0RTtgSl/kAW+8NWO8Abu0AbuwBZNsAg/8AYPwAc/MIVecAZuEAVeAAWt8AZN0JgvAIfOsJV+sTVuIAU9qil9AQAAAAa3RSTlMAAwb++A3+bkkkGxL8+Pf36tnTubCYjol4dmVjRjEvLysZFA7+/Pv6+fj39/b19fPw8O/u7Ovq6Ofn5+Xj4uDa2trZ1dPS0s/Ny7+9vLi4trapoqGgoJ2XkI+KgoJycGRhX1BNS0pHQj06IcCB3jkAAAIBSURBVDjLdZCHctpAFEWfCMU1ce8tTu+99957770nJFGwkE1sgyMTAginYbkAIQSD494+0G+ltTAacWZnNLt7dO/Og3Tqzl2og8wsvroAudEI+iy5s+6LzMZ7Bp1r5sFOQegRenAJwoEnoCXr6Mc0ihvSrhuK32vJK21Mva00760OWyz0KZYNbzJQmKXUF1o7rZ24rGngweETIGOwbH2nw/ZDUaM6grJVHzSs3R+NoqDy+lKLuwWX2618r03/QRalhNzbewo+qZyuZX4TVMFQubm3f3xy5VeZg49xsL8IC+mUH+1zeLyJ3pHkRCwWK7hvIGc/CYrwvIhtbXZ4hgYwJLm0LFf56QdhDRAq8wdZMypD3kT/SBJo6nfCMmWTc2WQlUO8GDIn2GSAUnuWGERJpIS4LR4HlWdFNITua9pl5s3h5vJ81tzscAAhuyTc3kZQ51CxqasvMmDGENyZyo1BX2iqLRAI0L7qvU2fv6Ex5mVbgana4XIGfb7QsI0KNcc4O4/Gv67I6Jjn5cmOvy4nGuFwaFipqFjN2YlBQkZn/N0dxAhiSfjUKzqHyxwq/0lIX0T0d6OAGb7dD0Gl/gzH8UqN6JcNp7HcBPN5esTO8U2oSCIpcZVkgwamepedxxpJROP4C9DBdHc9vlWSxG1VDOiTc53jpRW3TJCZ+vMXNeWzDz4DoNZyqecAAAAASUVORK5CYII=">
<link rel="apple-touch-icon" href="https://qn.cache.wpscdn.cn/kdocs/mobile/touch/apple-120.png">AI干活 xxx
给AI一个大致的方向,然后直接鞭策AI,叫AI给我们写,我就直接可以抽空玩我的手游去了 爱壹帆国际版 小宝影院在线视频
给出干活的指令: 免费在线影院
然后获取可能是ico的link标签,设置权重, 小寶影院电影
获取href 然后补全href图标路径 ifun 爱壹帆影视
然后再加一点点细节,设置重定向,伪造随机的User-Agent,ssl认证校验,href的相对路径和完整路径处理等
aiyifan电影
if ($html && $html['status'] == 'OK') {
// 对取到的HTML内容进行删除换行符的处理,避免link信息折行导致的正则匹配失败
$html = str_replace(array("\n", "\r"), '', $html);
//匹配完整的LINK标签,再从LINK标签中获取HREF的值
// 优化的两步匹配策略:先匹配所有link标签,再筛选favicon相关的标签
// 第一步:匹配所有link标签
$all_links = [];
if (preg_match_all('/<link[^>]*>/i', $html['data'], $link_matches)) {
$all_links = $link_matches[0];
}
$this->_log_message("【LINK匹配】找到 " . count($all_links) . " 个link标签");
// 定义favicon相关的rel类型及其优先级(数字越小优先级越高)
$favicon_types = [
'icon' => 1,
'shortcut icon' => 2,
'apple-touch-icon' => 3,
'apple-touch-icon-precomposed' => 4,
'mask-icon' => 5,
'alternate icon' => 6
];
$found_icons = [];
// 第二步:从所有link标签中筛选favicon相关的标签
foreach ($all_links as $link_tag) {
$this->_log_message("【LINK分析】处理标签: " . htmlspecialchars($link_tag));
// 提取rel属性值
$rel_value = '';
if (preg_match('/rel\s*=\s*["\']([^"\']*)["\']|rel\s*=\s*([^\s>]+)/i', $link_tag, $rel_matches)) {
$rel_value = trim($rel_matches[1] ?? $rel_matches[2] ?? '');
}
// 检查是否为favicon相关的rel类型
$matched_type = null;
$priority = 999;
foreach ($favicon_types as $type => $type_priority) {
// 使用更精确的匹配,避免部分匹配导致的错误识别
if ($type === 'icon' && preg_match('/^icon$/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
} elseif ($type === 'shortcut icon' && preg_match('/^shortcut\s+icon$/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
} elseif ($type === 'apple-touch-icon' && preg_match('/^apple-touch-icon/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
} elseif ($type === 'apple-touch-icon-precomposed' && preg_match('/^apple-touch-icon-precomposed/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
} elseif ($type === 'mask-icon' && preg_match('/^mask-icon$/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
} elseif ($type === 'alternate icon' && preg_match('/^alternate\s+icon$/i', trim($rel_value))) {
if ($type_priority < $priority) {
$matched_type = $type;
$priority = $type_priority;
}
}
}
if ($matched_type) {
$this->_log_message("【LINK分析】匹配到favicon类型: {$matched_type}, rel值: {$rel_value}");
// 提取href属性值
$href_value = '';
if (preg_match('/href\s*=\s*["\']([^"\']*)["\']|href\s*=\s*([^\s>]+)/i', $link_tag, $href_matches)) {
$href_value = trim($href_matches[1] ?? $href_matches[2] ?? '');
}
if (!empty($href_value)) {
$this->_log_message("【LINK分析】提取到href: {$href_value}");
// 处理URL路径
if (preg_match('/^data:image\/[^;]+;base64,/', $href_value)) {
$full_icon_url = $href_value;
} elseif (preg_match('/^https?:\/\//', $href_value)) {
$full_icon_url = $href_value;
} else {
$full_icon_url = $this->filterRelativeUrl($href_value, $this->params['origin_url']);
}
// 避免重复添加相同的URL
$icon_key = md5($full_icon_url);
if (!isset($found_icons[$icon_key])) {
$found_icons[$icon_key] = [
'url' => $full_icon_url,
'type' => $matched_type,
'priority' => $priority,
'original_rel' => $rel_value
];
}
} else {
$this->_log_message("【LINK分析】未找到href属性");
}
} else {
$this->_log_message("【LINK分析】非favicon标签,rel值: {$rel_value}");
}
}
// 按优先级排序图标
uasort($found_icons, function($a, $b) {
return $a['priority'] - $b['priority'];
});
// 打印所有找到的ICO路径
$this->_log_message("【ICO路径】找到 " . count($found_icons) . " 个favicon链接:");
foreach ($found_icons as $key => $icon_info) {
$this->_log_message("【ICO路径】类型: {$icon_info['type']}, 优先级: {$icon_info['priority']}, 原始rel: {$icon_info['original_rel']}, URL: {$icon_info['url']}");
}
// 尝试获取找到的favicon,按优先级顺序
foreach ($found_icons as $icon_info) {
$icon_url = $icon_info['url'];
$this->_log_message("Trying favicon URL ({$icon_info['type']}): {$icon_url}");
// 检查是否为 base64 data URI
if (preg_match('/^data:image\/[^;]+;base64,(.+)$/i', $icon_url, $matches)) {
$this->_log_message("Found base64 data URI favicon");
$base64_data = $matches[1];
// 解码 base64 数据
$decoded_data = base64_decode($base64_data);
if ($decoded_data !== false && strlen($decoded_data) > 0) {
$this->_log_message("Successfully decoded base64 favicon data, size: " . strlen($decoded_data) . " bytes");
$this->data = $decoded_data;
return $this->data; // 成功获取到 base64 favicon,直接返回
} else {
$this->_log_message("Failed to decode base64 favicon data");
}
} else {
// 普通的 HTTP/HTTPS URL,使用原有的 getFile 方法
$icon = $this->getFile($icon_url, true);
if ($icon && $icon['status'] == 'OK') {
$this->_log_message("Success get icon from {$this->params['origin_url']}, icon url is {$icon_url}");
$this->data = $icon['data'];
break; // 找到第一个可用的就停止
} else {
$this->_log_message("Failed to get icon from: {$icon_url}");
}
}
}
}直接叫AI改写核心的逻辑,到这一步已经大幅度的提升了获取icon的成功概率 电影爱壹帆
进阶优化 爱壹帆电影

到这一步已经解决了兼容绝大部分的站点,但是还有有一些特殊的展示无法兼容,这个时候就需要继续鞭策AI新增一个备用方案,支持手动映射站点和文件图标,解决剩下的无法获取图标的站点。
PHP我也没咋用过,直接叫AI自己出方案自己实现,新增可手动映射列表管理后台,并且可导出导入备份功能,简易后台维护系统 。
最终AI的技术栈选的SqLite+本地文件的形式做数据存储,非常的方便,也不需要依赖其他中间件了。
通过API自动识别+后台手动配置的方式,至此绝大部分站点都可以轻松的获取到图标。如果后续还遇到不兼容的站点,直接去管理后台配置一下就好了。 爱壹帆 华人影视

结束
AI越来越强悍了,全程花了几个小时,我一行代码没写,AI全程帮我完成了,我完全不会的PHP项目改造。自己写我可能就直接考虑换成自己熟悉的语言重写了,比如NodeJs代替。 爱一帆电影 xxxx
10目录 0