BeautifulSoup的用法

此文檔是根據(jù)BeautifulSoup4.4.0官方文檔總結(jié)而來(lái)

BeautifulSoup中的對(duì)象

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

Tag(標(biāo)簽)

# tag就是Tag對(duì)象未巫,對(duì)象的name是html標(biāo)簽名撞牢,也就是p
soup = BeautifulSoup('<p id="test_id" class="test-class">hello world!</p>','lxml')
tag = soup.p
# html里p的attributes也就變成了tag的attributes
tag['class']  ==>  ['test-class']  #class可能是多個(gè),所以是個(gè)數(shù)組
tag['id']  ==>  'test_id' #id只會(huì)是一個(gè)

NavigableString(標(biāo)簽里的內(nèi)容)

上面說(shuō)的p標(biāo)簽轉(zhuǎn)成tag對(duì)象刷允,那p標(biāo)簽里的內(nèi)容則會(huì)轉(zhuǎn)成字符串對(duì)象

# str就是NavigableString對(duì)象瞳别,
str = tag.string
# tag中字符串不能被編輯,但是可以替換成其他字符串
str.replace_with('yes')
print(tag)  ==>  <p class="test-class" id="test_id">yes</p>

BeautifulSoup(文檔對(duì)象)

BeautifulSoup對(duì)象和tag類(lèi)似沛励,但是它沒(méi)有name和attribute屬性

Comment(注釋)

一個(gè)html頁(yè)面吁断,里面除了標(biāo)簽,還有注釋部分槐壳,這就需要Comment對(duì)象

#Comment對(duì)象也是通過(guò)Tag對(duì)象來(lái)獲取然低,得到的是注釋里面的內(nèi)容
soup = BeautifulSoup('<p><!-- 注釋部分 --></p>','lxml')
comment = soup.p.string   ==>  注釋部分

遍歷文檔樹(shù)

示例html

html_doc = """
    <html>
        <head>
            <title>The Dormouse story</title>
        </head>
        <body>
            <p class="title">
                <b>The Dormouse 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>
        </body>
    </html>
    """

子節(jié)點(diǎn)

soup = BeautifulSoup(html_doc,'lxml')
# 獲取第一個(gè)a標(biāo)簽
soup.a
# 獲取所有的a標(biāo)簽
soup.find_all('a')
# tag的.contents屬性可以將tag的子節(jié)點(diǎn)以列表方式輸出
soup.head.contents  ==>  ['\n', <title>The Dormouse story</title>, '\n']
soup.head.contents[1].contents  ==>  ["The Dormouse story"]
# .children對(duì)tag直接子節(jié)點(diǎn)循環(huán)
for child in head.children:
    print (child)   ==>  <title>The Dormouse story</title>
# .descendants對(duì)tag所有子節(jié)點(diǎn)遞歸循環(huán)
for child in head.descendants:
    print (child)   ==>  <title>The Dormouse story</title> 和 The Dormouse story
# 當(dāng)tag中有多個(gè)字符串時(shí),使用strings务唐,去除空格用stripped_strings
for string in soup.stripped_strings:
    print (repr(string))

父節(jié)點(diǎn)

# .parent獲取元素父節(jié)點(diǎn)
soup.title.parent
# .parent遞歸查找所有父節(jié)點(diǎn)
soup.a.parents
# .next_sibling下一個(gè)兄弟節(jié)點(diǎn)雳攘,.previous_sibling上一個(gè)兄弟節(jié)點(diǎn)
# .next_siblings和.previous_siblings遞歸查找兄弟節(jié)點(diǎn)

搜索文檔樹(shù)

方法參數(shù)

# 字符串。查找所有b標(biāo)簽
soup.find_all('b')
# 正則表達(dá)式枫笛。查找所有以b開(kāi)頭的標(biāo)簽
import re
soup.find_all("^b")
# 列表吨灭。查找所有a標(biāo)簽和b標(biāo)簽
soup.find_all(['a','b'])
# True。查找所有
soup.find_all(True)
# 方法刑巧⌒郑可以將方法作為參數(shù),方法返回True或者False啊楚,find_all()據(jù)此查找
# 查找所有包含class屬性但不包含id屬性的元素
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)

find_all()

find_all(name,attrs,recursive,string,**kwargs)

# name參數(shù)吠冤。根據(jù)tag的name查找
soup.find_all('title')
# attrs參數(shù)。根據(jù)class查找恭理,但是class是python的保留字拯辙,需要用class_
soup.find_all('a',class_='sister')
soup.find_all('a',attrs={'class':'sister'})
# recursive參數(shù)。recursive=False查找直接子節(jié)點(diǎn)
soup.head.find_all('title',recursive=False)
# string參數(shù)颜价。與文檔中字符串內(nèi)容匹配涯保。
soup.find_all('a',string='Elsie')
# kwargs參數(shù)诉濒。自定義參數(shù)
soup.find_all(id='link2')
soup.find_all(href=re.compile("elsie"))
soup.find_all(id=True)
# limit參數(shù)。
soup.find_all('a',limit=2)

find_all()是最常用的方法之一夕春,因此可以簡(jiǎn)寫(xiě)未荒,例如

#這兩個(gè)等價(jià),寫(xiě)法和上面的Tag一樣
soup.find_all('a')  ==>  soup('a')

find()

find_all(name,attrs,recursive,string,**kwargs)

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

#這兩個(gè)等價(jià)
soup.find_all('a',limit=1)  ==>  soup.find('a')

其他搜索

find_parents() 和 find_parent() 向上查找

find_next_siblings() 和 find_next_sibling() 向后查找

find_previous_siblings() 和 find_previous_sibling() 向前查找

CSS選擇器

# .select()可以使用css語(yǔ)法查找Tag
soup.select('title')
soup.select('html head title')
soup.select('html>head>title')
soup.select('.sister')
soup.select('#link1')
soup.select_one('.sister')

輸出

格式化輸出

# prettify()將文檔格式化輸出
print(soup.prettify())

壓縮輸出

# unicode()和str()可以將文檔壓縮輸出
str(soup)  ==>  返回UTF-8編碼的字符串
unicode(soup)  ==>  返回Unicode編碼字符串

輸出文本內(nèi)容

# get_text()輸出tag包括子孫tag中的內(nèi)容(Unicode字符串)
soup.get_text()
# 指定分隔符
soup.get_text('|')
# 去除前后空白
soup.get_text('|',strip=True)
# 獲得文本列表
soup.stripped_strings

編碼

任何HTML或XML文檔都有自己的編碼方式,比如ASCII 或 UTF-8,但是使用Beautiful Soup解析后,文檔都被轉(zhuǎn)換成了Unicode

# .original_encoding 顯示編碼結(jié)果
soup.original_encoding
# from_encoding 指定編碼方式
soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
# exclude_encodings 不使用此編碼方式
soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])

輸出編碼

通過(guò)Beautiful Soup輸出文檔時(shí),不管輸入文檔是什么編碼方式,輸出編碼均為UTF-8編碼

# 使用prettify()修改輸出編碼
print(soup.prettify("latin-1"))
# 調(diào)用encode()方法指定編碼
soup.p.encode("utf-8")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撇他,一起剝皮案震驚了整個(gè)濱河市茄猫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌困肩,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脆侮,死亡現(xiàn)場(chǎng)離奇詭異锌畸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)靖避,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)潭枣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人幻捏,你說(shuō)我怎么就攤上這事盆犁。” “怎么了篡九?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵谐岁,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我榛臼,道長(zhǎng)伊佃,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任沛善,我火速辦了婚禮航揉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘金刁。我一直安慰自己帅涂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布尤蛮。 她就那樣靜靜地躺著媳友,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抵屿。 梳的紋絲不亂的頭發(fā)上庆锦,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音轧葛,去河邊找鬼搂抒。 笑死艇搀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的求晶。 我是一名探鬼主播焰雕,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼芳杏!你這毒婦竟也來(lái)了矩屁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤爵赵,失蹤者是張志新(化名)和其女友劉穎吝秕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體空幻,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烁峭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秕铛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片约郁。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖但两,靈堂內(nèi)的尸體忽然破棺而出鬓梅,到底是詐尸還是另有隱情,我是刑警寧澤谨湘,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布绽快,位于F島的核電站,受9級(jí)特大地震影響悲关,放射性物質(zhì)發(fā)生泄漏谎僻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一寓辱、第九天 我趴在偏房一處隱蔽的房頂上張望艘绍。 院中可真熱鬧,春花似錦秫筏、人聲如沸诱鞠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)航夺。三九已至,卻和暖如春崔涂,著一層夾襖步出監(jiān)牢的瞬間阳掐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缭保,地道東北人汛闸。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像艺骂,于是被迫代替她去往敵國(guó)和親诸老。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348