find_all

Every match, limit, and recursive.

find_all returns a list of every match (possibly empty). limit= stops early. recursive=False looks only at direct children.

Goal

List every link, cap the list, and search one level deep.

Every match

html = """
<html>
  <body>
    <a href="/nairobi/">Nairobi</a>
    <a href="/mombasa/">Mombasa</a>
    <a href="/kisumu/">Kisumu</a>
  </body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")
print(len(soup.find_all("a")))
for a in soup.find_all("a"):
    print(a.get_text())

soup("a") is a shortcut for soup.find_all("a").

limit

html = """
<ul>
  <li>Nairobi</li>
  <li>Mombasa</li>
  <li>Kisumu</li>
  <li>Nakuru</li>
</ul>
"""
soup = BeautifulSoup(html, "html.parser")
print([li.get_text() for li in soup.find_all("li", limit=2)])

recursive=False

html = """
<div>
  <p>outer</p>
  <section>
    <p>inner</p>
  </section>
</div>
"""
soup = BeautifulSoup(html, "html.parser")
div = soup.div
print("all p", [p.get_text() for p in div.find_all("p")])
print("direct p", [p.get_text() for p in div.find_all("p", recursive=False)])
You should see

When you already know CSS, select is often shorter than find_all.