BeautifulSoup4基礎(chǔ)

對(duì)象的種類
BeautifulSoup會(huì)將HTML文檔抓換成一個(gè)樹形結(jié)構(gòu), 每個(gè)節(jié)點(diǎn)都是Python對(duì)象玷过,所有對(duì)象可以分為4類:Tag,NavigableString,BeautifulSoup,Comment。

Tag

Tag與XML或HTML中的tag相同:

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

--<class 'bs4.element.Tag'>
--<b class="boldest">Extremely bold</b>
name

每一個(gè)Tag都有自己的name颗圣,可以通過.name秒际。改變tag的name,將會(huì)影響通過當(dāng)前BS對(duì)象生成的HTML文檔

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>',"html.parser")
tag = soup.b
print(tag)
print(tag.name)
tag.name="blockquote"
print(tag)

---<b class="boldest">Extremely bold</b>
---b
---<blockquote class="boldest">Extremely bold</blockquote>
attributes

一個(gè)tag可能有多個(gè)屬性

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>',"html.parser")
tag = soup.b
print(tag['class'])
print(tag.attrs)

---['boldest']
---{'class': ['boldest']}
tag的屬性可以被添加,刪除或修改

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>',"html.parser")
tag = soup.b

更改屬性

tag['class']="verybold"
tag['id']=1
print(tag)

刪除屬性

del tag['class']
print(tag)
print(tag.get('class'))

---<b class="verybold" id="1">Extremely bold</b>
---<b id="1">Extremely bold</b>


多值屬性

多值屬性即為可包含多個(gè)值的屬性赦抖,最常見的即為class
xml中沒有多值屬性

多值屬性的返回類型是list

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

---['body', 'strikeout']
若某個(gè)屬性看起來像多值屬性,但是在任何版本HTML中都沒有被定義為多值屬性辅肾,那么BS會(huì)將這個(gè)屬性作為字符串返回

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

---my id
NavigableString

NavigableString不支持.content,.string,find()方法队萤。

如果想在Beautiful Soup之外使用NavigableString對(duì)象,需要調(diào)用unicode()方法,將該對(duì)象轉(zhuǎn)換成普通的Unicode字符串,否則就算Beautiful Soup已方法已經(jīng)執(zhí)行結(jié)束,該對(duì)象的輸出也會(huì)帶有對(duì)象的引用地址.這樣會(huì)浪費(fèi)內(nèi)存.

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>',"html.parser")
tag = soup.b
print(tag.string)
print(type(tag.string))
tag.string.replace_with("No long bold")
print(tag)

---Extremely bold
---<class 'bs4.element.NavigableString'>
---<b class="boldest">No long bold</b>
BeautifulSoup
BeautifulSoup對(duì)象表示的是一個(gè)文檔的全部?jī)?nèi)容.大部分時(shí)候,可以把它當(dāng)作 Tag 對(duì)象,它支持 遍歷文檔樹 和 搜索文檔樹 中描述的大部分的方法.

BeautifuSoup沒有name和attribute屬性。但有一個(gè)值為[document]的特殊屬性.name

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>',"html.parser")
print(soup.name)

---[document]
Comment

遍歷文檔樹
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 class="sister" id="link1">Elsie</a>,
<a class="sister" id="link2">Lacie</a> and
<a class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""
.content和.children

tag的.contents屬性可以將tag的子節(jié)點(diǎn)以列表的方式輸出:
通過tag的.children生成器,可以對(duì)tag的子節(jié)點(diǎn)進(jìn)行循環(huán):

print(soup.title.contents)
print(soup.title.contents[0])

---["The Dormouse's story"]
---The Dormouse's story
for i in soup.head.children:
print(i)

---<title>The Dormouse's story</title>
.descendants

.descendants屬性可以對(duì)所有tag的子孫節(jié)點(diǎn)進(jìn)行遞歸循環(huán)

print(soup.head.contents)
for child in soup.head.descendants:
print(child)

print(len(list(soup.children)))
print(len(list(soup.descendants)))

---[<title>The Dormouse's story</title>]
---<title>The Dormouse's story</title>
---The Dormouse's story
---2
---25
.string

如果tag只有一個(gè)NavigableString類型子節(jié)點(diǎn),那么這個(gè)tag可以使用.string得到子節(jié)點(diǎn)

print(soup.head.string)

---The Dormouse's story
.strings和stripped_strings

如果tag中有多個(gè)字符串宛瞄,可以使用.strings循環(huán)獲取
使用.stripped_strings可以去除多余空白內(nèi)容:

for string in soup.stripped_strings:
print(repr(string))
.parent和.parents

通過.parent屬性來獲取某個(gè)元素的父節(jié)點(diǎn)
通過元素的.parents屬性可以遞歸得到元素的所有父輩節(jié)點(diǎn)浮禾。

for parent in soup.a.parents:
if parent is None:
print(parent)
else:
print(parent.name)

---p
---html
---[document]
兄弟節(jié)點(diǎn)

.next_sibling和.previous_sibling

使用。next_sibling和.previous_sibling屬性來查詢兄弟節(jié)點(diǎn)

實(shí)際文檔中的tag的 .next_sibling 和 .previous_sibling 屬性通常是字符串或空白份汗。因?yàn)橹虚g可能會(huì)隔著一些字符以及標(biāo)點(diǎn)盈电。

.next_siblings和.previous_siblings

for sibling in soup.a.next_siblings:
print(repr(sibling))

---',\n'
---<a class="sister" id="link2">Lacie</a>
---' and\n'
---<a class="sister" id="link3">Tillie</a>
';\nand they lived at the bottom of a well.'
重現(xiàn)解析過程

.next_element和.previous_element

next_element屬性指向解析過程中下一個(gè)被解析的對(duì)象(字符串或tag),結(jié)果可能與.next_sibling相同,但通常是不一樣的.

last_a_tag=soup.find("a",id="link3")
print(last_a_tag)
print(last_a_tag.next_sibling)
print(last_a_tag.next_element)

---<a class="sister" id="link3">Tillie</a>
---;
---and they lived at the bottom of a well.
---Tillie
.next_elements和.previous_elements

搜索文檔樹
過濾器

字符串

正則表達(dá)式

for tag in soup.find_all(re.compile("^b")):
print(tag.name)
列表

如果傳入列表參數(shù),Beautiful Soup會(huì)將與列表中任一元素匹配的內(nèi)容返回.

True

True可以匹配任何值,但是不會(huì)返回字符串節(jié)點(diǎn)

方法

如果沒有合適過濾器,那么還可以定義一個(gè)方法,方法只接受一個(gè)元素參數(shù),如果這個(gè)方法返回True表示當(dāng)前元素匹配并且被找到,如果不是則反回False。

def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')
find_all()

name參數(shù)

keyword參數(shù)

soup.find_all(id='link2')

按CSS搜索

因?yàn)閏lass是python保留字杯活,所以用class_
例:
soup.find_all("a",class_="sister")

class_參數(shù)同樣接受不同類型的過濾器 ,字符串,正則表達(dá)式,方法或 True :

tag的class屬性是 多值屬性 .按照CSS類名搜索tag時(shí),可以分別搜索tag中的每個(gè)CSS類名:

text參數(shù)

通過text參數(shù)可以搜搜文檔中的字符串內(nèi)容.

limit參數(shù)

limit參數(shù)限制返回結(jié)果的數(shù)量

recursive參數(shù)

調(diào)用tag的find_all()方法時(shí),Beautiful Soup會(huì)檢索當(dāng)前tag的所有子孫節(jié)點(diǎn),如果只想搜索tag的直接子節(jié)點(diǎn),可以使用參數(shù) recursive=False.

簡(jiǎn)寫

soup.find_all("a")
soup("a")
soup.title.find_all(text=True)
soup.title(text=True)
find()

只返回一個(gè)結(jié)果

find_parents()和find_parent()

find_next_siblings()和find_next_sibling()`

find_all_next()和find_next()

find_all_previous()和find_previous()

CSS選擇器

在Tag或BeautifulSoup對(duì)象的.select()方法中傳入字符串參數(shù),即可使用CSS選擇器的語(yǔ)法找到tag:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末匆帚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子旁钧,更是在濱河造成了極大的恐慌吸重,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歪今,死亡現(xiàn)場(chǎng)離奇詭異嚎幸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寄猩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門嫉晶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事替废」棵” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵椎镣,是天一觀的道長(zhǎng)诈火。 經(jīng)常有香客問我,道長(zhǎng)状答,這世上最難降的妖魔是什么冷守? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮剪况,結(jié)果婚禮上教沾,老公的妹妹穿的比我還像新娘。我一直安慰自己译断,他們只是感情好授翻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孙咪,像睡著了一般堪唐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翎蹈,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天淮菠,我揣著相機(jī)與錄音,去河邊找鬼荤堪。 笑死合陵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澄阳。 我是一名探鬼主播拥知,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碎赢!你這毒婦竟也來了低剔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤肮塞,失蹤者是張志新(化名)和其女友劉穎襟齿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枕赵,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猜欺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拷窜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片开皿。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钓试,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出副瀑,到底是詐尸還是另有隱情,我是刑警寧澤恋谭,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布糠睡,位于F島的核電站,受9級(jí)特大地震影響疚颊,放射性物質(zhì)發(fā)生泄漏狈孔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一材义、第九天 我趴在偏房一處隱蔽的房頂上張望均抽。 院中可真熱鬧,春花似錦其掂、人聲如沸油挥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)深寥。三九已至,卻和暖如春贤牛,著一層夾襖步出監(jiān)牢的瞬間惋鹅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工殉簸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闰集,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓般卑,卻偏偏與公主長(zhǎng)得像武鲁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子椭微,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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