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.