You need to grab a website's favicon in a Python script — maybe for a link preview, a bookmark manager, or a monitoring dashboard. The good news: you don't need a heavy browser automation tool. A few lines with requests and BeautifulSoup will do the job.

This tutorial shows you exactly how to write a python get favicon from url function that handles the common cases. We'll cover parsing the HTML, falling back to /favicon.ico, and saving the binary file.

Prerequisites

You'll need Python 3.7+ and two libraries: requests and beautifulsoup4. Install them with pip:

pip install requests beautifulsoup4

If you prefer not to parse HTML manually, you can also use a library like favicon (available on PyPI), but we'll build it from scratch for full control.

Step 1: Fetch the page HTML

Start by downloading the page source. Use a realistic User-Agent header — some servers block default 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

Always set a timeout. Without it, a slow server can hang your script indefinitely.

Step 2: Look for link rel="icon" tags

The HTML spec defines rel="icon" as the standard way to declare a favicon. Browsers also accept shortcut icon and apple-touch-icon. We'll check all of them, preferring SVG and PNG over 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'

Note the use of urljoin — favicon hrefs are often relative (e.g., /assets/favicon.png), and you need to resolve them against the page URL.

Step 3: Download and save the icon

Once you have the URL, fetch the binary content and write it to a file. Check the Content-Type header to pick an extension.

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

That's the core logic. You can wrap both functions into a single script that takes a URL from the command line.

Common pitfalls

If you need to extract multiple icon formats (Apple Touch, manifest icons), consider using a dedicated tool like Mzu favicondl to inspect all available icons. For a deeper dive into favicon formats, see our favicon format guide.

Conclusion

You now have a working Python function to get a favicon from any URL. The key steps are: fetch the page, parse the <link> tags, resolve relative URLs, and download the binary. Handle errors and edge cases, and you're set.

Remember to respect robots.txt and rate limits when scraping many sites. For a complete favicon solution, check out our PHP tutorial for comparison.

Check the documented requirements

The HTML Standard defines rel='icon' as the link relationship for an icon representing the current page.