繼上一篇BeautifulSoup的高級應用,主要解說的是contents children descendants string strings stripped_strings。本篇主要解說.parent .parents .next_sibling .previous_sibling .next_siblings .previous_siblings
本篇博客繼續使用上篇的html頁面內容:
html_doc = """
<html>
<head><title>The Dormouse's story</title></head>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p>
<p class="story">...</p>
</html>"""
繼續分析文檔樹 ,每一個 tag或字符串都有父節點 :被包括在某個 tag中
.parent:
通過 .parent 屬性來獲取某個元素的父節點.在樣例html文檔中,標簽是標簽的父節點:
title_tag = soup.title
title_tag
# <title>The Dormouse's story</title>
title_tag.parent
# <head><title>The Dormouse's story</title></head>
文檔title的字符串也有父節點:標簽
title_tag.string.parent
# <title>The Dormouse's story</title>
文檔的頂層節點比方的父節點是 BeautifulSoup 對象:
html_tag = soup.html
type(html_tag.parent)
# <class 'bs4.BeautifulSoup'>
BeautifulSoup 對象的 .parent 是None。
.parents:
通過元素的.parents屬性能夠遞歸得到元素的全部父輩節點 , 以下的樣例使用了 .parents方 法遍歷了 標簽到根節點 的全部節點:
link = soup.a
link
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
for parent in link.parents:
if parent is None:
print(parent)
else:
print(parent.name)
# p
# body
# html
# [document]
# None
兄弟節點:
舉例說明:
<a>
<b>text1</b>
<c>text2</c>
</a>
這里的b和c節點為兄弟節點
.next_sibling 和 .previous_sibling .:
在文檔樹中 ,使用 .next_sibling 和 .previous_sibling 屬性來查詢兄弟節點:
sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>")
sibling_soup.b.next_sibling
# <c>text2</c>
sibling_soup.c.previous_sibling
# <b>text1</b>
b 標簽有.next_sibling 屬性 ,可是沒有 .previous_sibling 屬性 ,由於 b標簽在同級節點中是第一個 .同理 ,c標簽有 .previous_sibling 屬性 ,卻沒有 .next_sibling 屬性 。
link = soup.a link
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
link.next_sibling
# u',\n'
注意:第一個a標簽的next_sibling 屬性值為 。\n
link.next_sibling.next_sibling
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
第一個a標簽的next_sibling的next_sibling 屬性值為Lacie
.next_siblings 和 .previous_siblings.:
通過 .next_siblings 和 .previous_siblings 屬性對當前節點的兄弟節點迭代輸出:
for sibling in soup.a.next_siblings:
print(repr(sibling)) # u',\n'
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
# u' and\n'
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
# u'; and they lived at the bottom of a well.'
# None
for sibling in soup.find(id="link3").previous_siblings: print(repr(sibling))
# ' and\n'
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
# u',\n'
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
# u'Once upon a time there were three little sisters; and their names were\n'
# None
回退和前進:
舉例html例如以下:
<html><head><title>The Dormouse's story</title></head> <p class="title"><b>The Dormouse's story</b></p>
HTML 解析器把這段字符串轉換成一連的事件 : “ 打開標簽 ”加入一段字符串 ”,關閉 標簽 ”,”打開
標簽 ”, 等.Beautiful Soup提供了重現解析器初始化過程的方法
.next_element 和 .previous_element .
.next_element 屬性指向解析過程中下一個被的對象 (字符串或 tag),結果可能 與 .next_sibling 同樣 ,但一般是不一樣的 .
last_a_tag = soup.find("a", id="link3")
last_a_tag
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
last_a_tag.next_sibling
# '; and they lived at the bottom of a well.'
但這個 標簽的 .next_element 屬性結果是在標簽被解析之后的內容 ,不是 標 簽后的句子部分 ,應該是字符串 ”Tillie”:
last_a_tag.next_element
# u'Tillie'
.previous_element 屬性剛好與.next_element 相反 ,它指向當前被解 析的對象的前一個解析對象 :
last_a_tag.previous_element
# u' and\n'
last_a_tag.previous_element.next_element
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
.next_elements 和 .previous_elements:
通過 .next_elements 和 .previous_elements 的迭代器就能夠向前或后訪問文檔解析內容 ,就好像文檔正在被解析一樣 :
for element in last_a_tag.next_elements: print(repr(element))
# u'Tillie'
# u';\nand they lived at the bottom of a well.'
# u'\n\n'
# <p class="story">...</p>
# u'...'
# u'\n'
# None
下一篇 將解說一下BeautifulSoup的搜索文檔樹的高級方法。