Skillversitas

Parents and Siblings Navigation

Beautiful Soup lets you move up and sideways in the tree. From any node you can reach its parent and grandparents with .parent and .parents, and its horizontal neighbors with .next_sibling and .previous_sibling.

.parent - One Level Up

from bs4 import BeautifulSoup

html = "<table><tr><td>cell</td></tr></table>"
soup = BeautifulSoup(html, "html.parser")

td = soup.find("td")
print(td.parent.name)     # tr
print(td.parent.parent.name)  # table

If the node has no parent (it is the root), .parent is None.

.parents - All Ancestors

for p in td.parents:
    print(p.name)  # tr, table, [document]

.parents walks upward to the root, yielding each ancestor tag in order. It is useful for "find the enclosing section" problems:

def enclosing(tag, name):
    for p in tag.parents:
        if p.name == name:
            return p
    return None

.next_sibling and .previous_sibling

Siblings are the nodes immediately before or after you in the parent's .contents. Text nodes count as siblings, so you will often see whitespace strings:

html = "<ul><li>one</li><li>two</li></ul>"
soup = BeautifulSoup(html, "html.parser")

li = soup.find("li")
print(repr(str(li.next_sibling)).strip())   # whitespace text node
print(li.next_sibling.next_sibling.name)    # the second <li>

.next_siblings and .previous_siblings

The plural forms are generators over all following or preceding siblings, which is cleaner than chaining .next_sibling twice:

for sib in soup.find("li").next_siblings:
    if getattr(sib, "name", None) == "li":
        print(sib.get_text())  # two

Summary

Move up the tree with .parent and .parents, and sideways with .next_sibling, .previous_sibling, and their plural generator forms. Remember that whitespace text nodes are siblings too, so filter by tag name when you only want elements.