100行代码实现 favicon 小工具

这几天查看统计的时候发现统计页面的小图标不显示了。

图标变成了一个白色方框,这个umami 一直无法加载 favicon,之前换成了:https://favicon.cccyun.cc/h4ck.org.cn

现在这个服务貌似证书过期了,也没人维护,看来也没多少人用啊:

本着能动手尽量别 bb 的理念,既然不能用了那就自建服务吧。

个人觉得最简单的代码还是通过 python 实现,依赖于 flask + favicon 库,只需要一百行代码就 ok 了。实现方式,通过 favicon 库获取图标,将图标数据缓存到 redis,再次请求直接返回 redis 缓存数据。完整代码如下:

import json

from flask import Flask, request, redirect, jsonify
import favicon
import redis
import json
from urllib.parse import urlparse

app = Flask(__name__)

rds = redis.Redis(host='localhost', port=6379, db=1)


def get_domain_from_url(url):
    parsed_uri = urlparse(url)
    return 'https://{uri.netloc}'.format(uri=parsed_uri)


def get_query_count():
    key = 'QUERY_COUNT'
    count = 1
    if rds.exists(key):
        count = int(rds.get(key))
    return count


def set_query_count():
    key = 'QUERY_COUNT'
    count = 1
    if rds.exists(key):
        count = int(rds.get(key))
        count += 1
    rds.set(key, count)
    return count


def get_icon_list_from_rds(key):
    if rds.exists(key):
        # print('cached')
        cashed = rds.get(key)
        js = json.loads(cashed)
        return js
    icons = favicon.get(key)
    # rds.set('url',icons,)
    icon_list = []
    for i in icons:
        data = {
            'url': i.url,
            'width': i.width,
            'height': i.height,
            'format': i.format
        }
        icon_list.append(data)
    js_str = json.dumps(icon_list)
    rds.setex(key, 86400, js_str)
    return icon_list


@app.route('/')
def hello_world():  # put application's code here

    return ('--------------------------- <br> '
            'Query count:' + str(get_query_count()) + '<br>'
                                                      '=========================== <br> '
                                                      'Baby Favicon Tool v1.0  \r\n<br> by:obaby \r\n <br><a href="https://oba.by" target="_blank">https://oba.by</a> <br>\r\r '
                                                      '<a href="https://h4ck.org.cn" target="_blank">https://h4ck.org.cn</a>')


# http://127.0.0.1:5000/api/get_favicon?url=https://h4ck.org.cn
@app.route('/api/get_favicon')
def search():
    query = request.args.get('url')
    if '.' not in query:
        return 'invalid url'
    if not query.startswith('http'):
        query = 'http://' + query

    icons = get_icon_list_from_rds(query)
    set_query_count()
    # icons_str = json.dumps(icons)
    return jsonify(icons)


@app.route('/api/redirect_favicon')
def redirect_icon():
    query = request.args.get('url')
    if '.' not in query:
        return 'invalid url'
    if not query.startswith('http'):
        query = 'http://' + query
    set_query_count()
    icons = get_icon_list_from_rds(query)
    try:
        icon_url = icons[0]['url']
    except:
        icon_url = 'https://h4ck.org.cn/wp-content/uploads/2024/09/favicon.png'
    return redirect(icon_url, code=302)


if __name__ == '__main__':
    app.run()

到这里这个服务就算完成了,后续就是通过 nginx 反代了,经常反代的朋友都回了,我就不写了。

修改 umami 源代码:vim umami/src/components/common/Favicon.tsx

修改划线部分为上述内容,重新编译即可,编译过程中很可能会卡在 build-geo.修改 build 脚本 vim scripts/build-geo.js

这个破玩意儿 bug 之处在于,如果使用 github 代理,下载过程会出错,第二部分的实时解压就挂了,这个逻辑也是 tm 神了,不能下载完再解压吗?

直接下载第一处gz 文件解压,将 GeoLite2-City.mmdb放入geo 目录下,注释掉第二部分执行 yarn build 即可。不得不多,这 dq 真是给程序员创建了无数的便利,就尼玛离谱。重新启动服务一切就 ok 了。

图标又回来了,现有服务地址: https://favicon.h4ck.org.cn (不保证服务可用性,有时候的确是懒不想折腾了,之前的 gravatar 忽然因为 cdn 问题就失效了,结果删除重建也不行就放弃了。这个实属无奈,但是基本都会保证一个可用的服务。)

使用方法:

接口:  
1. 获取 favicon 数据,返回 json 格式  
http://127.0.0.1:5000/api/get_favicon?url=oba.by  
返回数据内容:  
```json
[
  {
    "format": "png",
    "height": 300,
    "url": "https://oba.by/wp-content/uploads/2020/09/icon-500-300x300.png",
    "width": 300
  },
  {
    "format": "png",
    "height": 200,
    "url": "https://oba.by/wp-content/uploads/2020/09/icon-500-200x200.png",
    "width": 200
  },
  {
    "format": "png",
    "height": 192,
    "url": "https://oba.by/wp-content/uploads/2020/09/icon-500-200x200.png",
    "width": 192
  },
  {
    "format": "png",
    "height": 32,
    "url": "https://oba.by/wp-content/uploads/2020/09/icon-500-100x100.png",
    "width": 32
  },
  {
    "format": "ico",
    "height": 0,
    "url": "https://oba.by/favicon.ico",
    "width": 0
  },
  {
    "format": "jpg",
    "height": 0,
    "url": "https://h4ck.org.cn/screenshots/obaby_tuya.jpg",
    "width": 0
  }
]
```
2. 直接返回 favicon 链接  
http://127.0.0.1:5000/api/redirect_favicon?url=oba.by  
返回数据内容为上述接口的第一个结果,例如上面的 域名将会直接 302跳转到 https://oba.by/wp-content/uploads/2020/09/icon-500-300x300.png  
如果没有 favicon 将会返回默认连接:https://h4ck.org.cn/wp-content/uploads/2024/09/favicon.png

代码地址:

https://github.com/obaby/baby-favicon-tool.git

☆版权☆

* 网站名称:obaby@mars
* 网址:https://nai.dog/
* 个性:https://oba.by/
* 本文标题: 《100行代码实现 favicon 小工具》
* 本文链接:https://nai.dog/2024/09/18075
* 短链接:https://oba.by/?p=18075
* 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。


You may also like

63 comments

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      g.obaby.blog 这个还是可以的,目前我用的是这个。那个不知道 cdn 怎么抽风了,死活不能回源。

  1. Level 5
    Google Chrome 109 Google Chrome 109 Windows 10 Windows 10 cn上海市 腾讯云

    亮丝和肉丝比,还是更爱灵妹妹的肉丝

  2. Level 4
    Microsoft Edge 129 Microsoft Edge 129 Windows 10 Windows 10 cn江苏省宿迁市 移动

    前几天我也在折腾favicon,前、后台显示不一样,而follow里不显示,为了一个上图标,也折腾了一晚上。

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      这个东西,网上也找了几个地址,发现有的根本获取不到。
      所以就自建了

        1.  Level 6
          Google Chrome 107 Google Chrome 107 Android 14 Android 14 cn北京市 联通

          尴尬啦,好像有的上cdn没法获取。😂我用获取主体大部分都是海外。估计被防御挡住了。

          1. Level 2
            Google Chrome 122 Google Chrome 122 Windows 10 Windows 10 cn贵州省贵阳市 移动

            应该不是cdn!我的可以获取哦

            1. 公主 Queen 
              Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

              可能跟我的 cdn 策略有关系,国外默认开启防御,之前天天被 cc 攻击。

          2. 公主 Queen 
            Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

            可能跟防御策略有关系,国外是默认开启的。不然老有沙雕来 cc

  3. Level 4
    Google Chrome 129 Google Chrome 129 Mac OS X 10.15 Mac OS X 10.15 cn广东省清远市 电信

    好方法,测试了一下,不但拿到了favicon,连封面图都能获取到。 dance good

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      啊。还有这个意外收获,这倒没注意。哈哈哈

  4.  Level 4
    Google Chrome 128 Google Chrome 128 Mac OS X 10.15 Mac OS X 10.15 cn江苏省徐州市 电信

    姐的图片都是存哪的 cry 又拍云被盗刷两百多都不敢用了 cry

  5. Level 3
    Safari 17 Safari 17 Mac OS X 10.15 Mac OS X 10.15 cn北京市 电信

    之前看到好多开源php版本的,还是有些图片获取不到,get了。👍

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      你说的是这个东西吗?https://h4ck.org.cn/my-devices

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      主要是站在巨人的肩上,确实没啥难度,哈哈哈

      1. Level 2
        Google Chrome 101 Google Chrome 101 Windows 10 Windows 10 cn湖北省武汉市 电信

        我也是一言不合就开始改,不过还是太懒啦,怎么简单怎么来

        1. 公主 Queen 
          Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

          一百来行代码能解决的就干,超过一千行就想放弃了。😂

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn山东省青岛市 联通

      umami自带的是需要开梯子的(用的 duckduckgo 的https://icons.duckduckgo.com/ip3/),后来我给换了,结果这个也挂了,就不如自建一个。

      1. Level 1
        Google Chrome 124 Google Chrome 124 Windows 10 Windows 10 cn山东省青岛市 联通

        另一方面,就是你编程代码能力强哈。毫不费力的感觉。

  6.  Level 6
    Google Chrome 129 Google Chrome 129 Windows 10 Windows 10 cn北京市 电信

    当时RSS朋友圈就是因为这个问题,走了捷径,调用{foto-1},回头再调回来 dance dance

  7.  Level 6
    Google Chrome 128 Google Chrome 128 Mac OS X 10.15 Mac OS X 10.15 cn北京市 联通

    我找了下我之前的插件代码,gpt生成的,用了一个平台 ,应该是一个第三方的库。

  8. Level 1
    Google Chrome 129 Google Chrome 129 Windows 10 Windows 10 cn河北省邢台市 联通

    厉害,厉害,技术女神,感觉会写代码的都很牛逼,那么会写代码的女神就更不简单了。哈哈

  9.  Level 2
    Microsoft Edge 129 Microsoft Edge 129 Windows 11 Windows 11 cn上海市徐汇区 联通/漕河泾数据中心

    看来,我得给我的网站做一个“统计”页面了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注