Skillversitas

The find Method

.find() searches the parse tree and returns the first tag that matches your filter, or None if nothing matches. It accepts a tag name, an attribute filter, a function, or a combination, making it the most versatile single search method in Beautiful Soup.

By Tag Name

from bs4 import BeautifulSoup

html = "<div><p>first</p><section><p>nested</p></section></div>"
soup = BeautifulSoup(html, "html.parser")

print(soup.find("p"))            # <p>first</p>
print(soup.find("nosuch"))       # None

By Attributes

Pass attributes as keyword arguments. The class attribute is written class_ because class is a Python keyword:

html = "<ul><li id="a">x</li><li class="hot">y</li></ul>"
soup = BeautifulSoup(html, "html.parser")

print(soup.find("li", id="a"))            # <li id="a">x</li>
print(soup.find("li", class_="hot"))      # <li class="hot">y</li>
print(soup.find(attrs={"data-x": "1"}))   # any tag with data-x="1"

limit and recursive

limit bounds the number of matches scanned (find always returns at most one tag, but limit can stop the search early), and recursive=False restricts the search to direct children:

html = "<div><p>direct</p><span><p>indirect</p></span></div>"
soup = BeautifulSoup(html, "html.parser")

print(soup.find("p"))                # <p>direct</p>
print(soup.find("p", recursive=False))  # None (no direct <p> child of soup? it has <div>)

Function Filters

For logic that is awkward to express as attributes, pass a function that receives a tag and returns True or False:

def is_big_heading(tag):
    return tag.name == "h2" and tag.get("class") and "big" in tag.get("class")

print(soup.find(is_big_heading))

Summary

find() returns the first matching tag or None. Filter by name, by attributes (class_ for the class attribute, attrs=dict for arbitrary names), by a custom function, and control scope with limit and recursive=False. Always guard against None before reading the result.