Python:bs4中 string 屬性和 text 屬性的區別及背後的原理

剛開始接觸 bs4 的時候,我也很迷茫,以爲 string 屬性和 text 屬性是同樣的,不明白爲何要分紅兩個屬性。html

html = '<p>hello world</p>' soup = BeautifulSoup(html, 'lxml') p = soup.p print(p.string)  # hello word
print(p.text)    # hello word

輸出的結果是同樣的。但實際上,string 屬性的返回類型是 bs4.element.NavigableString,而 text 屬性的返回類型是 str。post

print(type(p.string))   # <class 'bs4.element.NavigableString'>
print(type(p.text))     # <class 'str'>

不要小看了這點區別,看下面的示例:url

html = '''<html> <td>some text</td> <td></td> <td><p>more text</p></td> <td>even <p>more text</p></td> </html>''' soup = BeautifulSoup(html, 'lxml') tds = soup.find_all('td') for td in tds: print(td.string) for td in tds: print(td.text)

string 屬性的輸出結果爲:spa

some text
None
more text
None

text 屬性的輸出結果爲:code

some text

more text
even more text

理解了 string 屬性和 text 屬性的返回類型,就能夠明白結果爲何是這樣的了。xml

第一項,返回都是 「some text」,這能夠理解;htm

第二項,string 返回 None,由於不存在 NavigableString 節點;blog

第三項,text 返回的是標籤的全部字符串鏈接成的字符串,因此是「more text」element

第四項,bs4 的文檔中指出:(地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#string)文檔

  若是 tag 只有一個 NavigableString 類型子節點,那麼這個 tag 可使用 .string 獲得子節點。
  若是一個 tag 僅有一個子節點,那麼這個 tag 也可使用 .string 方法,輸出結果與當前惟一子節點的 .string 結果相同。
  若是 tag 包含了多個子節點,tag 就沒法肯定 .string 方法應該調用哪一個子節點的內容, .string 的輸出結果是 None。

  那麼天然 string 屬性返回的結果是 None,text 屬性返回的結果是「even more text」

 

另外,要注意的是 find 方法中的 text 參數,官方解釋是:text 參數用於搜索字符串會找到 .string 方法與 text 參數值相符的tag。

也就是說,雖然參數名是 text,但實際上搜索的是 string 屬性。

 

看下面的例子,咱們須要查找到包含附件連接的<a>標籤

html = '''<div>
    <p> 附件: <a href='xxx'>下載</a></p>
</div> '''

用 string 屬性來獲取的話,代碼以下:

soup = BeautifulSoup(html, 'lxml') tab = soup.find(text=re.compile('附件')) print(type(tab))    # <class 'bs4.element.NavigableString'>
print(tab)          # 附件

能夠看到獲取到的是 NavigableString 標籤,要獲取<a>標籤,能夠配合 find_next_sibling() 方法。

若是使用使用 text 屬性的話,就必須傳遞方法來實現,但結果可能就不是你想要的了

 

def txt(tag): return re.search('附件', tag.text) is not None print(soup.find_all(txt))

 

結果以下,把每一層顯示的都包含進來了。

[<html><body><div>
<p> 附件: <a href="xxx">下載</a></p>
</div>
</body></html>, <body><div>
<p> 附件: <a href="xxx">下載</a></p>
</div>
</body>, <div>
<p> 附件: <a href="xxx">下載</a></p>
</div>, <p> 附件: <a href="xxx">下載</a></p>]

 


相關博文推薦:

Python:bs4的使用

Python:requests:詳解超時和重試

相關文章
相關標籤/搜索