【Python 庫】bs4 中 string 屬性和 text 屬性的區別及背后的原理


剛開始接觸 bs4 的時候,我也很迷茫,覺得 string 屬性和 text 屬性是一樣的,不明白為什么要分成兩個屬性。

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。

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

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

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 屬性的輸出結果為:

some text
None
more text
None

text 屬性的輸出結果為:

some text

more text
even more text

理解了 string 屬性和 text 屬性的返回類型,就可以明白結果為什么是這樣的了。

第一項,返回都是 “some text”,這可以理解;

第二項,string 返回 None,因為不存在 NavigableString 節點;

第三項,text 返回的是標簽的所有字符串連接成的字符串,所以是“more text”

第四項,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:詳解超時和重試

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM