BeautifulSoup(markup, "html.parser") turns a string into a tree. Dot-access (soup.h1) is the first tag of that name.
Goal
Parse a tiny page, print the heading, and list the links.
Title and heading
html = """
<html>
<head><title>Kenya kiosk</title></head>
<body>
<h1>Nairobi kiosk</h1>
<p>Open today.</p>
</body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")
print(soup.title)
print(soup.title.string)
print(soup.h1.get_text()).string is the text node inside a tag that has only text. get_text() walks descendants and is safer when a tag has nested tags.
Links
html = """
<html>
<body>
<h1>Nairobi kiosk</h1>
<a href="/nairobi/">Nairobi</a>
<a href="/mombasa/">Mombasa</a>
</body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")
for a in soup.find_all("a"):
print(a.get_text(), "->", a.get("href"))Each block is a complete script. The workbench does not keep soup from the previous Run.
Pitfall
BeautifulSoup(html) without a parser name may pick a parser you do not have. Always pass "html.parser".