find_next, find_previous and Friends
find_next and find_previous search forward or backward through the flat document from a starting node, not from the root. They are the right tools when the answer to "which element?" depends on position relative to something you already found.
find_next
from bs4 import BeautifulSoup
html = "<p>Label: <span>x</span></p><div><b>value</b></div>"
soup = BeautifulSoup(html, "html.parser")
span = soup.find("span")
print(span.find_next("b").get_text()) # value
find_next accepts the same filters as find (name, attributes, text, function), and returns None when nothing later in the document matches.
find_previous
b = soup.find("b")
print(b.find_previous("span").get_text()) # x
find_all_next and find_all_previous
The plural forms return a list of all later or earlier matches:
html = "<p>start</p><b>1</b><b>2</b><b>3</b>"
soup = BeautifulSoup(html, "html.parser")
p = soup.find("p")
print([b.get_text() for b in p.find_all_next("b")]) # ['1', '2', '3']
b3 = soup.find_all("b")[2]
print([b.get_text() for b in b3.find_all_previous("b")]) # ['2', '1']
Practical Pattern: Field Next to a Label
Forms and definition lists are classic use cases: locate the label text, then take the next meaningful element:
html = "<dt>Author</dt><dd>Ada L.</dd>"
soup = BeautifulSoup(html, "html.parser")
label = soup.find("dt")
print(label.find_next("dd").get_text(strip=True)) # Ada L.
Summary
find_next/find_previous (and their find_all_* plural forms) search relative to a node's position in the document instead of from the root. Use them for position-dependent extraction like "the value after this label", and apply the usual None guards to the result.