Beautiful Soup4學(xué)習(xí)筆記(二):對象的種類

Beautiful Soup將復(fù)雜HTML文檔轉(zhuǎn)換成一個復(fù)雜的樹形結(jié)構(gòu),每個節(jié)點(diǎn)都是Python對象,所有對象可以歸納為4種: Tag , NavigableString , BeautifulSoup , Comment 库倘。

1:Tag

Tag對象與XML或HTML原生文檔中的tag相同:

>>> soup=BeautifulSoup('<b class="boldest">Extremely bold</b>')
>>> tag = soup.b 
>>> tag 
<b class="boldest">Extremely bold</b>
>>> type(tag) 
<class 'bs4.element.Tag'>

Tag有很多方法和屬性.現(xiàn)在介紹一下tag中最重要的屬性: name和attributes

Name

每個tag都有自己的名字临扮,通過 .name來獲取

>>> tag.name
'b'

如果改變了tag的name,那將影響所有通過當(dāng)前Beautiful Soup對象生成的HTML文檔:

>>> tag.name = 'blockquote' 
>>> tag
<blockquote class="boldest">Extremely bold</blockquote>

Attributes

一個tag可能有很多個屬性. tag <b class="boldest"> 有一個 “class” 的屬性,值為 “boldest” .
tag的屬性的操作方法與字典相同:

>>> tag['class'] 
['boldest']

也可以直接“點(diǎn)”取屬性于樟,比如: .attrs:

>>> tag.attrs
{'class': ['boldest']}

tag的屬性可以被添加,刪除或修改. 再說一次, tag的屬性操作方法與字典一樣

>>> tag['class'] = 'verybold' 
>>> tag['id'] = 1 
>>> tag
<b class="verybold" id="1">Extremely bold</b>
>>> del tag['class'] 
>>> del tag['id'] 
>>> tag
<b>Extremely bold</b>
>>> tag['class']
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    tag['class']
  File "/usr/local/lib/python3.5/site-packages/bs4/element.py", line 997, in __getitem__
    return self.attrs[key]
KeyError: 'class'
>>> print(tag.get('class'))
None

多值屬性

最常見的多值的屬性是 class (一個tag可以有多個CSS的class). 還有一些屬性 rel , rev , accept-charset , headers , accesskey . 在Beautiful Soup中多值屬性的返回類型是list:

>>> css_soup = BeautifulSoup('<p class="body strikeout"></p>')  
>>> css_soup.p['class']   
['body', 'strikeout']
>>> css_soup = BeautifulSoup('<p class="body"></p>')  
>>> css_soup.p['class']   
['body']

如果某個屬性看起來好像有多個值,但在任何版本的HTML定義中都沒有被定義為多值屬性,那么Beautiful Soup會將這個屬性作為字符串返回

>>> id_soup = BeautifulSoup('<p  id="my id"></p>') 
>>> id_soup.p['id'] 
'my id'

將tag轉(zhuǎn)換成字符串時公条,多值屬性會合并為一個值

>>> rel_soup = BeautifulSoup('<p>Back to the <a rel="index">homepage</a></p>') 
>>> rel_soup.a['rel'] 
['index']
>>> rel_soup.a['rel'] = ['index','contents'] 
>>> print(rel_soup.p) 
<p>Back to the <a rel="index contents">homepage</a></p>

如果轉(zhuǎn)換的文檔時XML格式,那么tag中不包含多值屬性

>>> xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')  
>>> xml_soup.p['class'] 
'body strikeout'

2:可遍歷的字符串

字符串常被包含在tag內(nèi).Beautiful Soup用 NavigableString 類來包裝tag中的字符串:

>>> tag.string
'Extremely bold'
>>> type(tag.string)
<class 'bs4.element.NavigableString'>

一個 NavigableString 字符串與Python中的Unicode字符串相同,并且還支持包含在 遍歷文檔樹 和 搜索文檔樹 中的一些特性. 通過 unicode() 方法可以直接將 NavigableString 對象轉(zhuǎn)換成Unicode字符串:

unicode_string = unicode(tag.string)
unicode_string
# u'Extremely bold'
type(unicode_string)
# <type 'unicode'>

上面的轉(zhuǎn)換迂曲,python3.5好像不支持靶橱,倒是支持轉(zhuǎn)化為string:

>>> str(tag.string) 
'Extremely bold'
>>> type(str(tag.string))
<class 'str'>

tag中包含的字符串不能編輯,但是可以被替換成其它的字符串路捧,用replace_with()方法:

>>> tag.string.replace_with("No longer bold") 
'Extremely bold'
>>> tag
<b class="boldest">No longer bold</b>

NavigableString 對象支持 遍歷文檔樹 和 搜索文檔樹 中定義的大部分屬性, 并非全部.尤其是,一個字符串不能包含其它內(nèi)容(tag能夠包含字符串或是其它tag),字符串不支持 .contents 或 .string 屬性或 find() 方法.
如果想在Beautiful Soup之外使用 NavigableString 對象,需要調(diào)用 unicode() 方法,將該對象轉(zhuǎn)換成普通的Unicode字符串,否則就算Beautiful Soup的方法已經(jīng)執(zhí)行結(jié)束,該對象的輸出也會帶有對象的引用地址.這樣會浪費(fèi)內(nèi)存.

3:BeautifulSoup

BeautifulSoup 對象表示的是一個文檔的全部內(nèi)容.大部分時候,可以把它當(dāng)作 Tag 對象,它支持 遍歷文檔樹 和 搜索文檔樹 中描述的大部分的方法.

因?yàn)?BeautifulSoup 對象并不是真正的HTML或XML的tag,所以它沒有name和attribute屬性.但有時查看它的 .name 屬性是很方便的,所以 BeautifulSoup 對象包含了一個值為 “[document]” 的特殊屬性 .name

>>> soup.name
'[document]'

4:注釋及特殊字符串(Comment)

Tag , NavigableString , BeautifulSoup 幾乎覆蓋了html和xml中的所有內(nèi)容,但是還有一些特殊對象.容易讓人擔(dān)心的內(nèi)容是文檔的注釋部分:

>>> markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
>>> soup = BeautifulSoup(markup)
>>> comment = soup.b.string
>>> type(comment)
<class 'bs4.element.Comment'>

Comment對象是一個特殊類型的NavigableString對象:

>>> comment 
'Hey, buddy. Want to buy a used parser?'

但是當(dāng)它出現(xiàn)在HTML文檔中時, Comment 對象會使用特殊的格式輸出:

>>> print(soup.b.prettify())
<b>
 <!--Hey, buddy. Want to buy a used parser?-->
</b>

Beautiful Soup中定義的其它類型都可能會出現(xiàn)在XML的文檔中: CData , ProcessingInstruction , Declaration , Doctype .與 Comment 對象類似,這些類都是 NavigableString 的子類,只是添加了一些額外的方法的字符串獨(dú)享.下面是用CDATA來替代注釋的例子:

>>> from bs4 import CData
>>> cdata = CData("A CDATA block")
>>> comment.replace_with(cdata) 
'Hey, buddy. Want to buy a used parser?'
>>> print(soup.b.prettify())
<b>
 <![CDATA[A CDATA block]]>
</b>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末关霸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子杰扫,更是在濱河造成了極大的恐慌队寇,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件章姓,死亡現(xiàn)場離奇詭異佳遣,居然都是意外死亡识埋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門零渐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窒舟,“玉大人,你說我怎么就攤上這事诵盼』莶颍” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵风宁,是天一觀的道長洁墙。 經(jīng)常有香客問我,道長戒财,這世上最難降的妖魔是什么热监? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮饮寞,結(jié)果婚禮上狼纬,老公的妹妹穿的比我還像新娘。我一直安慰自己骂际,他們只是感情好疗琉,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歉铝,像睡著了一般盈简。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上太示,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天柠贤,我揣著相機(jī)與錄音,去河邊找鬼类缤。 笑死臼勉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的餐弱。 我是一名探鬼主播宴霸,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膏蚓!你這毒婦竟也來了瓢谢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤驮瞧,失蹤者是張志新(化名)和其女友劉穎氓扛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體论笔,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡采郎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年千所,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒜埋。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡真慢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出理茎,到底是詐尸還是另有隱情,我是刑警寧澤管嬉,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布皂林,位于F島的核電站,受9級特大地震影響蚯撩,放射性物質(zhì)發(fā)生泄漏础倍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一胎挎、第九天 我趴在偏房一處隱蔽的房頂上張望沟启。 院中可真熱鬧,春花似錦犹菇、人聲如沸德迹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胳搞。三九已至,卻和暖如春称杨,著一層夾襖步出監(jiān)牢的瞬間肌毅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工姑原, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悬而,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓锭汛,卻偏偏與公主長得像笨奠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唤殴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容