Pythonスクリプトでウェブサイトのfaviconを取得したい場面はあるでしょう。リンクプレビュー、ブックマークマネージャー、監視ダッシュボードなどが考えられます。良いニュースは、重厚なブラウザ自動化ツールは不要だということです。requestsとBeautifulSoupを使えば数行で済みます。
このチュートリアルでは、一般的なケースに対応するpython get favicon from url関数の書き方を具体的に示します。HTMLの解析、/favicon.icoへのフォールバック、バイナリファイルの保存までを扱います。
前提条件
Python 3.7以上と2つのライブラリ、requestsとbeautifulsoup4が必要です。pipでインストールします。
pip install requests beautifulsoup4HTMLを手動で解析したくない場合は、PyPIで入手できるfaviconのようなライブラリも使えますが、ここでは完全に制御するためにゼロから構築します。
ステップ1: ページのHTMLを取得する
まずページのソースをダウンロードします。現実的なUser-Agentヘッダーを使用してください。一部のサーバーはデフォルトのPythonリクエストをブロックします。
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必ずタイムアウトを設定してください。設定しないと、遅いサーバーがスクリプトを無期限にハングさせる可能性があります。
ステップ2: link rel="icon"タグを探す
HTML仕様では、faviconを宣言する標準的な方法としてrel="icon"が定義されています。ブラウザはshortcut iconやapple-touch-iconも受け入れます。ここではそれらすべてをチェックし、ICOよりSVGとPNGを優先します。
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これが中核となるロジックです。2つの関数を1つのスクリプトにまとめれば、コマンドラインから URL を受け取れるようにできます。
よくある落とし穴
- 相対 URL:必ず
urljoinで解決してください。href="favicon.ico"のような相対 URL をそのまま使うと失敗します。 - リダイレクト:
requestsはデフォルトでリダイレクトを追跡しますが、最終的な URL は変わることがあります。正確さが必要な場合は、urljoinのベースとしてresp.urlを使ってください。 - favicon がない:多くのサイトには
/favicon.icoがありません。フォールバック処理は 404 を返すので、try/except で適切に処理してください。 - Content-Type の不一致:一部のサーバーは ICO ファイルを
image/x-iconまたはimage/vnd.microsoft.iconとして配信します。拡張子だけに依存しないでください。 - 大きなファイル:favicon は通常小さいですが、誤って巨大なファイルをダウンロードしないように、最大サイズ制限(例:1 MB)を設定してください。
複数の icon format(Apple Touch、manifest icons)を抽出する必要がある場合は、利用可能な icon をすべて調べられる Mzu favicondl のような専用ツールを検討してください。favicon の format の詳細については、favicon format ガイド を参照してください。
結論
これで、任意の URL から favicon を取得できる Python 関数が完成しました。重要な手順は、ページを取得し、<link> タグを解析し、相対 URL を解決し、バイナリをダウンロードすることです。エラーやエッジケースを処理すれば完了です。
多くのサイトをスクレイピングする場合は、robots.txtとレート制限を尊重してください。完全なfaviconソリューションについては、比較のためにPHPチュートリアルを確認してください。
文書化された要件を確認する
HTML Standardは、rel='icon'を、現在のページを表すアイコンのリンク関係として定義しています。