如果想在 Python 脚本中获取某个网站的 favicon,比如用于链接预览、书签管理器或监控面板,你不必引入笨重的浏览器自动化工具。用 requests 和 BeautifulSoup 写几行代码就能完成。

本文将完整演示如何编写一个 python get favicon from url 函数,并处理几种常见情况,包括解析 HTML、回退到 /favicon.ico,以及保存二进制文件。

前置条件

你需要 Python 3.7+,以及两个库:requests 和 beautifulsoup4。使用 pip 安装:

pip install requests beautifulsoup4

如果不想手动解析 HTML,也可以使用 favicon(可在 PyPI 获取)之类的库。不过,本文会从头实现,以便完全掌控处理过程。

步骤 1:获取页面 HTML

先下载页面源码。设置一个合理的 User-Agent 请求头,因为有些服务器会拦截 Python requests 的默认请求。

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse

def get_favicon_url(page_url):
    headers = {'User-Agent': 'Mozilla/5.0 (compatible; FaviconFetcher/1.0)'}
    resp = requests.get(page_url, headers=headers, timeout=10)
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, 'html.parser')
    # ... continue below

一定要设置 timeout。否则,响应缓慢的服务器可能让脚本一直卡住。

步骤 2:查找 rel="icon" 标签

HTML 规范将 rel="icon" 定义为声明 favicon 的标准方式。浏览器也接受 shortcut icon 和 apple-touch-icon。检查这些类型时,应优先选择 SVG 和 PNG,而不是 ICO。

    icon_link = soup.find('link', rel=lambda x: x and 'icon' in x.lower())
    if icon_link and icon_link.get('href'):
        return urljoin(page_url, icon_link['href'])
    # Fallback to /favicon.ico
    parsed = urlparse(page_url)
    return f'{parsed.scheme}://{parsed.netloc}/favicon.ico'

注意这里使用了 urljoin:favicon 的 href 往往是相对路径,例如 /assets/favicon.png,需要根据页面 URL 将其解析为完整地址。

步骤 3:下载并保存图标

拿到 URL 后,获取二进制内容并写入文件。检查 Content-Type 响应头,以选择文件扩展名。

def download_favicon(favicon_url, output_path='favicon.ico'):
    headers = {'User-Agent': 'Mozilla/5.0 (compatible; FaviconFetcher/1.0)'}
    resp = requests.get(favicon_url, headers=headers, timeout=10)
    resp.raise_for_status()
    content_type = resp.headers.get('Content-Type', '')
    if 'png' in content_type:
        output_path = output_path.replace('.ico', '.png')
    elif 'svg' in content_type:
        output_path = output_path.replace('.ico', '.svg')
    with open(output_path, 'wb') as f:
        f.write(resp.content)
    return output_path

这就是核心逻辑。可以把这两个函数封装到一个脚本中,让它从命令行接收 URL。

常见陷阱

如果需要提取多种图标格式(Apple Touch、manifest icons),可以考虑使用专门的工具,例如 Mzu favicondl,来检查所有可用图标。想深入了解 favicon 格式,可以参阅我们的 favicon 格式指南。

结论

现在,你已经有了一个可正常工作的 Python 函数,可以从任意 URL 获取 favicon。关键步骤包括:获取页面、解析 <link> 标签、解析相对 URL,以及下载二进制内容。处理好错误和边界情况后,就可以了。

抓取多个网站时,请务必遵守 robots.txt 和请求频率限制。如果需要完整的 favicon 解决方案,可以查看我们的 PHP 教程 作对比。

检查文档中规定的要求

HTML Standard 将 rel='icon' 定义为一种 link relationship,用于指定代表当前页面的 icon。