Python BeautifulSoup 中.text與.string的區別

Python BeautifulSoup 中.text與.string的區別

來自專欄 Python之路

用python寫爬蟲時,BeautifulSoup真是解析html,快速獲取所需數據的神器。

這個美味湯使喚起來,屢試不爽。

在用find()方法找到特定的tag後,想獲取裡面的文本,可以用.text屬性或者.string屬性。

在很多時候,兩者的返回結果一致,但其實兩者是有區別的。

.string的資料很多,.text的資料比較少。

遍尋中文世界沒有滿意的答案,直接google在stock overflow中找到了很滿意的解答:

.string on a Tag type object returns a NavigableString type object. On the other hand, .textgets all the child strings and return concatenated using the given separator. Return type of .text is unicode object.

From the documentation, A NavigableString is just like a Python Unicode string, except that it also supports some of the features described in Navigating the tree and Searching the tree.

From the documentation on .string, we can see that, If the html is like this,

<td>Some Table Data</td><td></td>

Then, .string on the second td will return None. But .text will return and empty string which is a unicode type object.

For more convenience,

string

  • Convenience property of a tag to get the single string within this tag.
  • If the tag has a single string child then the return value is that string.
  • If the tag has no children or more than one child the return value is None
  • If this tag has one child tag return value is the string attribute of the child tag, recursively.

And text

  • Get all the child strings and return concatenated using the given separator.

If the html is like this:

1、<td>some text</td> 2、<td></td>3 、<td><p>more text</p></td>4、<td>even <p>more text</p></td>

.string on the four td will return,

1some text2None3more text4None

.text will give result like this

1、some text2、more text3、even more text

通過以上的舉例,可以很清楚的發現,.find和.string之間的差異:

第一行,在指定標籤td,沒有子標籤,且有文本時,兩者的返回結果一致,都是文本

第二行,在指定標籤td,沒有子標籤,且沒有文本時,.string返回None,.text返回為空

第三行,在指定標籤td,只有一個子標籤時,且文本只出現在子標籤之間時,兩者返回結果一致,都返回子標籤內的文本

第四行,最關鍵的區別,在指定標籤td,有子標籤,並且父標籤td和子標籤p各自包含一段文本時,兩者的返回結果,存在很大的差異

.string返回為空,因為文本數>=2,string不知道獲取哪一個

.text返回的是,兩段文本的拼接。

【實踐舉例說明】

<p class="pTxt pIntroShow">簡介:故事發生在非洲附近的大海上,主人公冷鋒(吳京 飾)遭遇人生滑鐵盧,被「開除軍籍」,本想漂泊一生的他,正當他打算這麼做的時候,一場突如其來的意外打破了他的計劃,突然被捲入了一場非洲國家叛亂,本可以安全撤離,卻因無法忘記曾經為軍人的使命,孤身犯險沖回淪陷區,帶領身陷屠殺中的同胞和難民,展開生死逃亡。隨著斗... <a href="javascript:void(0);" target="_self" class="aMore pIntroShowMore">展開全部&nbsp;<i class="iconfont"></i></a></p>

當我在爬電影信息時,<p>tag內容,如上所示

一開始用的是.string,但是效果不理想,有些電影可以正常返回簡介,有些卻返回None

intro = movie.find(p, class_=pTxt pIntroShow).string

這是因為展現頁面會有文本長度的限制,有些電影簡介比較長,無法全部顯示,所以會在p標籤下增加子標籤a,而有些電影則沒有這個a,這時如果用string,有子標籤的會返回None,而沒有子標籤的,可以正常返回。

所以改用.text,不管有沒有子標籤,都能得到簡介,如果想去除『展開全部』,可以用一個replace函數。

intro = movie.find(p, class_=pTxt pIntroShow).text.replace(展開全部,)

以上的問題,也可以使用.strings,然後迭代判斷,但是語法沒有.text簡單

strings = movie.find(p, class_=pTxt pIntroShow).strings for string in strings: if string != 展開全部: intro = string break

此文參考:Edit

BeautifulSoup的教程很多,興趣的可以參考

Python爬蟲利器二之Beautiful Soup的用法

從零開始寫Python爬蟲


推薦閱讀:

技術專題—Python黑客【優質內容聚合貼】
使用Anaconda實現Python2和Python3共存及相互轉換
python計算機視覺編程
給Python函數執行前後添加額外行為

TAG:beautifulsoup | Python | 爬蟲 |