Next and Previous Elements
Beyond siblings there is .next_element and .previous_element, which move through the entire document in flat document order: tags and strings alike, across all levels of nesting. This is the navigation you need when the target is "whatever comes next in the page".
.next_element - The Next Node in Document Order
from bs4 import BeautifulSoup
html = "<p><b>bold</b> after </p><p>next para</p>"
soup = BeautifulSoup(html, "html.parser")
b = soup.find("b")
print(repr(str(b.next_element))) # ' after ' (text node)
print(repr(str(b.next_element.next_element))) # '</p>' closing? no - next text
Because strings are elements in this walk, the walk interleaves tags and text. Chaining a few .next_element steps quickly becomes unreadable, which is why the plural forms exist.
.previous_element - The Previous Node
p2 = soup.find_all("p")[1]
print(repr(str(p2.previous_element))) # whitespace before the <p>
.next_elements and .previous_elements
The plural forms yield every following or preceding element in document order:
for el in soup.find("b").next_elements:
text = str(el).strip()
if text:
print(text)
if isinstance(el, type(soup)) or getattr(el, "name", None) == "p":
break
Practical Pattern: Text After a Label
A common scraping task is "find the value next to the label". Walk .next_elements from the label and take the first non-whitespace string you hit:
label = soup.find(string="Price:")
for el in label.next_elements:
text = str(el).strip()
if text:
print("value:", text)
break
Summary
.next_element and .previous_element (and the plural generator forms) walk the document in flat order across tags and text. Use them for "what follows this label" problems, and break out of the walk as soon as you find the value you want.