BeautifulSoup4簡易食用指南

本文是對BeautifulSoup4官方文檔的簡化與填坑

Beautifulsoup4

1.安裝

1.1安裝Beautiful Soup4

利用python包管理工具pip可以十分簡單的安裝Beautiful Soup4

$ pip install beautifulsoup4 

1.2安裝第三方解析器lxml提高運行效率

Beautiful Soup支持Python標準庫中的HTML解析器,還支持一些第三方的解析器,其中一個是 lxml .
安裝方法

$ pip install lxml

PS: win下安裝lxml有坑,如果pip安裝報錯,參考StackOverflow上提供的解決方法

2.使用方法

from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
print(soup.prettify())

首先,文檔被轉(zhuǎn)換成Unicode,并且HTML的實例都被轉(zhuǎn)換成Unicode編碼揉抵。然后,Beautiful Soup選擇最合適的解析器來解析這段文檔,如果手動指定解析器那么Beautiful Soup會選擇指定的解析器來解析文檔

2.1 Beautiful Soup的對象

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

Tag

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

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

Tag中有name和attributes屬性

tag.name
# u'b'
tag['class']
# u'boldest'

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

NavigableString(可以遍歷的字符串)

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

tag.string
# u'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'>
BeautifulSoup

BeautifulSoup
對象表示的是一個文檔的全部內(nèi)容.大部分時候,可以把它當作 Tag
對象,它支持 遍歷文檔樹搜索文檔樹 中描述的大部分的方法.
因為 BeautifulSoup對象并不是真正的HTML或XML的tag,所以它沒有name和attribute屬性.但有時查看它的 .name屬性是很方便的,所以 BeautifulSoup對象包含了一個值為 “[document]” 的特殊屬性 .name

soup.name
# u'[document]'
Comment(注釋及特殊字符串)

Tag , NavigableString , BeautifulSoup 幾乎覆蓋了html和xml中的所有內(nèi)容,但是還有一些特殊對象.容易讓人擔心的內(nèi)容是文檔的注釋部分
PS:由于爬蟲一般不需要爬注釋,不展開躺屁。

2.2 遍歷文檔樹

PS:樹,好大的樹

獲取標簽內(nèi)容:

獲取標簽內(nèi)容和剝洋蔥差不多

soup = '''
<head><title>The Dormouse's story</title></head>
<title>Another Dormouse's story</title>
'''
soup.head
# <head><title>The Dormouse's story</title></head>
soup.head.title
# <title>The Dormouse's story</title>
soup.title 
# <title>The Dormouse's story</title>
soup.title.string
The Dormouse's story

可以看到使用title只能獲取到第一個title经宏,可以用find_all()需要獲取所有title犀暑,并返回一個list:

soup.find_all('title')
# [<title>The Dormouse's story</title>,<title>Another Dormouse's story</title>]

.contents ,.children烁兰,.descendants:

.contents 和 .children 屬性僅包含tag的直接子節(jié)點
.contents 屬性相當于剝一層洋蔥皮耐亏,并返回list:

head_tag = '''
<head><title>The Dormouse's story</title><title>Another Dormouse's story</title></head>
'''
head_tag.content
# [<title>The Dormouse's story</title>, <title>Another Dormouse's story</title>]

.children是列表迭代器,用for輸出:

html_doc = """<head><title>The Dormouse's story</title><title>T Dormouse's story</title></head>"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'lxml')

print(soup.head.children)
for child in soup.head.children:
    print(child)
# <list_iterator object at 0x10b66c710>
# <title>The Dormouse's story</title>
# <title>T Dormouse's story</title> 

.descendants 屬性和.children類似沪斟,不同的是.children只能訪問一層子節(jié)點广辰,而可以對所有tag的子孫節(jié)點進行遞歸循環(huán)

.strings 和以及更好的 stripped_strings

如果tag中包含多個字符串 ,可以使用 .strings來循環(huán)獲取,stripped_strings用于去除所有空白內(nèi)容,包括段落間空行:

.parent和.parents

.parent 屬性可以用來獲取某個元素的父節(jié)點择吊,.parents 屬性可以遞歸得到元素的所有父輩節(jié)點

兄弟節(jié)點

.next_sibling 和 .previous_sibling李根,.next_siblings 和 .previous_siblings:

在文檔樹中,使用 .next_sibling 和 .previous_sibling 屬性來查詢兄弟節(jié)點,通過 .next_siblings 和 .previous_siblings 屬性可以對當前節(jié)點的兄弟節(jié)點迭代輸出:

回退和前進

.next_element 和 .previous_element几睛,.next_elements 和 .previous_elements

.next_element 屬性指向解析過程中下一個被解析的對象(字符串或tag),結(jié)果可能與 .next_sibling 相同,但通常是不一樣的.通過 .next_elements 和 .previous_elements 的迭代器就可以向前或向后訪問文檔的解析內(nèi)容,就好像文檔正在被解析一樣.

2.3搜索文檔樹

find_all()

使用 find_all() 類似的方法可以查找到想要查找的文檔內(nèi)容房轿,find_all( name , attrs , recursive , text , **kwargs )

  • name 參數(shù)可以查找所有名字為 name 的tag,字符串對象會被自動忽略掉.
  • 如果一個指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名,搜索時會把該參數(shù)當作指定名字tag的屬性來搜索,如果包含一個名字為 id 的參數(shù),Beautiful Soup會搜索每個tag的”id”屬性.搜索指定名字的屬性時可以使用的參數(shù)值包括 字符串 , 正則表達式 , 列表, True .
  • 按照CSS類名搜索tag的功能非常實用,但標識CSS類名的關鍵字 class 在Python中是保留字,使用 class 做參數(shù)會導致語法錯誤.從Beautiful Soup的4.1.1版本開始,可以通過 class_ 參數(shù)搜索有指定CSS類名的tag:
  • 通過 text 參數(shù)可以搜搜文檔中的字符串內(nèi)容.與 name 參數(shù)的可選值一樣, text 參數(shù)接受 字符串 , 正則表達式 , 列表, True . 看例子:
  • find_all() 方法返回全部的搜索結(jié)構,如果文檔樹很大那么搜索會很慢.如果我們不需要全部結(jié)果,可以使用 limit 參數(shù)限制返回結(jié)果的數(shù)量.
  • 調(diào)用tag的 find_all() 方法時,Beautiful Soup會檢索當前tag的所有子孫節(jié)點,如果只想搜索tag的直接子節(jié)點,可以使用參數(shù) recursive=False
find_all('b')
# 返回所有b標簽


import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b
# 通過正則表達式返回含有b開頭的標簽


soup.find_all(["a", "b"])
# 返回含有a或b標簽的


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)
# [<p class="title"><b>The Dormouse's story</b></p>,
#  <p class="story">Once upon a time there were...</p>,
#  <p class="story">...</p>]
# 自定一種方法


find()

find('tag')相當于find_all('tag',limit = 1)

find_next_siblings() 合 find_next_sibling(),find_previous_siblings() 和 find_previous_sibling()

find_next_siblings( name , attrs , recursive , text , **kwargs )
find_next_sibling( name , attrs , recursive , text , **kwargs )
這2個方法通過 .next_siblings 屬性對當tag的所有后面解析 [5] 的兄弟tag節(jié)點進行迭代, find_next_siblings() 方法返回所有符合條件的后面的兄弟節(jié)點, find_next_sibling() 只返回符合條件的后面的第一個tag節(jié)點.
ind_previous_siblings( name , attrs , recursive , text , **kwargs )
find_previous_sibling( name , attrs , recursive , text , **kwargs )
這2個方法通過 .previous_siblings 屬性對當前tag的前面解析 [5] 的兄弟tag節(jié)點進行迭代, find_previous_siblings() 方法返回所有符合條件的前面的兄弟節(jié)點, find_previous_sibling() 方法返回第一個符合條件的前面的兄弟節(jié)點

find_all_next() 和 find_next()所森,find_all_previous() 和 find_previous()

find_all_next( name , attrs , recursive , text , **kwargs )囱持,find_next( name , attrs , recursive , text , **kwargs )
這2個方法通過 .next_elements 屬性對當前tag的之后的tag和字符串進行迭代, find_all_next() 方法返回所有符合條件的節(jié)點, find_next() 方法返回第一個符合條件的節(jié)點
find_all_previous( name , attrs , recursive , text , **kwargs ),find_previous( name , attrs , recursive , text , **kwargs )
這2個方法通過 .previous_elements 屬性對當前節(jié)點前面 [5] 的tag和字符串進行迭代, find_all_previous() 方法返回所有符合條件的節(jié)點, find_previous() 方法返回第一個符合條件的節(jié)點.

2.4 CSS選擇器

W3School上有關CSS選擇器相關介紹

2.5 修改文檔樹

由于目前我接觸到的爬蟲都很少涉及到修改數(shù)據(jù)焕济,有需要自行參看Beautifulsoup官方文檔

2.6 輸出

get_text()

如果只想得到tag中包含的文本內(nèi)容,那么可以嗲用 get_text() 方法,這個方法獲取到tag中包含的所有文版內(nèi)容包括子孫tag中的內(nèi)容,并將結(jié)果作為Unicode字符串返回:

PS:其他內(nèi)容請查看官方文檔

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纷妆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吼蚁,更是在濱河造成了極大的恐慌,老刑警劉巖问欠,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肝匆,死亡現(xiàn)場離奇詭異,居然都是意外死亡顺献,警方通過查閱死者的電腦和手機旗国,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來注整,“玉大人能曾,你說我怎么就攤上這事≈坠欤” “怎么了寿冕?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長椒袍。 經(jīng)常有香客問我驼唱,道長,這世上最難降的妖魔是什么驹暑? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任玫恳,我火速辦了婚禮,結(jié)果婚禮上优俘,老公的妹妹穿的比我還像新娘京办。我一直安慰自己,他們只是感情好帆焕,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布惭婿。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪审孽。 梳的紋絲不亂的頭發(fā)上县袱,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音佑力,去河邊找鬼式散。 笑死,一個胖子當著我的面吹牛打颤,可吹牛的內(nèi)容都是我干的暴拄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼编饺,長吁一口氣:“原來是場噩夢啊……” “哼乖篷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起透且,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤撕蔼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后秽誊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲸沮,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年锅论,在試婚紗的時候發(fā)現(xiàn)自己被綠了讼溺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡最易,死狀恐怖怒坯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情藻懒,我是刑警寧澤剔猿,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站嬉荆,受9級特大地震影響艳馒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜员寇,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一弄慰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝶锋,春花似錦陆爽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽别威。三九已至,卻和暖如春驴剔,著一層夾襖步出監(jiān)牢的瞬間省古,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工丧失, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留豺妓,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓布讹,卻偏偏與公主長得像琳拭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子描验,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

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