BeautifulSoup4解析器(css選擇器)

CSS 選擇器:BeautifulSoup4

官方文檔:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0

和 lxml 一樣年扩,Beautiful Soup 也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 數(shù)據(jù)媒峡。

  • lxml 只會局部遍歷糊渊,而Beautiful Soup 是基于HTML DOM的渺绒,會載入整個文檔,解析整個DOM樹躏鱼,因此時間和內(nèi)存開銷都會大很多染苛,所以性能要低于lxml主到。

  • BeautifulSoup 用來解析 HTML 比較簡單登钥,API非常人性化,支持CSS選擇器茉唉、Python標準庫中的HTML解析器度陆,也支持 lxml 的 XML解析器献幔。

  • Beautiful Soup 3 目前已經(jīng)停止開發(fā)蜡感,推薦現(xiàn)在的項目使用Beautiful Soup 4恃泪。使用 pip 安裝即可:pip3 install beautifulsoup4

抓取工具 速度 使用難度 安裝難度
正則 最快 困難 無(內(nèi)置)
BeautifulSoup 最簡單 簡單
lxml 簡單 一般

示例: 首先必須要導入 bs4 庫

# beautifulsoup4_test.py

from bs4 import BeautifulSoup

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""

#創(chuàng)建 Beautiful Soup 對象
soup = BeautifulSoup(html)

#也可以以打開本地 HTML 文件的方式來創(chuàng)建對象
#soup = BeautifulSoup(open('index.html'))

#格式化輸出 soup 對象的內(nèi)容
print(soup.prettify())

運行結(jié)果:

<html>
<head>
<title>
The Dormouse's story
</title>
</head>
<body>
<p class="title" name="dromouse">
<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>
</body>
</html>

如果我們在執(zhí)行時,看到這樣一段警告:

屏幕快照 2018-05-06 下午2.05.50.png
  • 意思是,如果我們沒有顯式地指定解析器虫几,所以默認使用這個系統(tǒng)的最佳可用HTML解析器(“l(fā)xml”)辆脸。如果你在另一個系統(tǒng)中運行這段代碼啡氢,或者在不同的虛擬環(huán)境中,使用不同的解析器造成行為不同浪箭。

  • 但是我們可以通過soup = BeautifulSoup(html,“l(fā)xml”)方式指定lxml解析器,如果'lxml'失敗,使用soup = BeautifulSoup(html,“html.parser”)

四大對象種類

  • Beautiful Soup將復雜HTML文檔轉(zhuǎn)換成一個復雜的樹形結(jié)構(gòu),每個節(jié)點都是Python對象,所有對象可以歸納為4種:
  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment
Tag 通俗點講就是 HTML 中的一個個標簽,例如:
<head><title>The Dormouse's story</title></head>
<a class="sister"  id="link1"><!-- Elsie --></a>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
上面的 title head a p等等 HTML 標簽加上里面包括的內(nèi)容就是 Tag门坷,那么試著使用 Beautiful Soup 來獲取 Tags:
from bs4 import BeautifulSoup
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
#創(chuàng)建 Beautiful Soup 對象
soup = BeautifulSoup(html,'lxml')
print(soup.title)
# <title>The Dormouse's story</title>
print(soup.head)
# <head><title>The Dormouse's story</title></head>
print(soup.a)
# <a class="sister"  id="link1"><!-- Elsie --></a>
print(soup.p)
# <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
print(type(soup.p))
# <class 'bs4.element.Tag'>
  • 我們可以利用 soup 加標簽名輕松地獲取這些標簽的內(nèi)容,這些對象的類型是bs4.element.Tag绸吸。但是注意设江,它查找的是在所有內(nèi)容中的第一個符合要求的標簽叉存。如果要查詢所有的標簽,后面會進行介紹稿存。

  • 對于 Tag瓣履,它有兩個重要的屬性袖迎,是 name 和 attrs

print(soup.name)
# [document] #soup 對象本身比較特殊,它的 name 即為 [document]

print (soup.head.name)
# head #對于其他內(nèi)部標簽浴韭,輸出的值便為標簽本身的名稱

print (soup.p.attrs)
# {'class': ['title'], 'name': 'dromouse'}
# 在這里念颈,我們把 p 標簽的所有屬性打印輸出了出來榴芳,得到的類型是一個字典跺撼。

print (soup.p['class'] # soup.p.get('class'))
# ['title'] #還可以利用get方法歉井,傳入屬性的名稱哩至,二者是等價的

soup.p['class'] = "newClass"
print soup.p # 可以對這些屬性和內(nèi)容等等進行修改
# <p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>
2. NavigableString

既然我們已經(jīng)得到了標簽的內(nèi)容菩貌,那么問題來了箭阶,我們要想獲取標簽內(nèi)部的文字怎么辦呢仇参?很簡單冈敛,用 .string 即可,例如

print (soup.p.string)
# The Dormouse's story

print (type(soup.p.string))
# In [13]: <class 'bs4.element.NavigableString'>
3. BeautifulSoup BeautifulSoup 對象表示的是一個文檔的內(nèi)容暮蹂。大部分時候,可以把它當作 Tag 對象仰泻,是一個特殊的 Tag集侯,我們可以分別獲取它的類型棠枉,名稱辈讶,以及屬性來感受一下
print type(soup.name)
# <type 'unicode'>

print soup.name 
# [document]

print soup.attrs # 文檔本身的屬性為空
# {}
4. Comment Comment 對象是一個特殊類型的 NavigableString 對象生闲,其輸出的內(nèi)容不包括注釋符號碍讯。
print soup.a
# <a class="sister"  id="link1"><!-- Elsie --></a>

print soup.a.string
# Elsie 

print type(soup.a.string)
# <class 'bs4.element.Comment'>
  • a 標簽里的內(nèi)容實際上是注釋捉兴,但是如果我們利用 .string 來輸出它的內(nèi)容時难衰,注釋符號已經(jīng)去掉了

CSS選擇器

  • 寫 CSS 時盖袭,標簽名不加任何修飾鳄虱,類名前加 '.' 拙已,id名前加 '#'

  • 在這里我們也可以利用類似的方法來篩選元素倍踪,用到的方法是 soup.select(),返回類型是 list

(1)通過標簽名查找
print(soup.select('title'))
#[<title>The Dormouse's story</title>]

print soup.select('a')
#[<a class="sister"  id="link1"><!-- Elsie --></a>, <a class="sister"  id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

print soup.select('b')
#[<b>The Dormouse's story</b>]
(2)通過類名查找
print soup.select('.sister')
#[<a class="sister"  id="link1"><!-- Elsie --></a>, <a class="sister"  id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]
(3)通過 id 名查找
print soup.select('#link1')
#[<a class="sister"  id="link1"><!-- Elsie --></a>]
(4)組合查找
  • 組合查找即和寫 class 文件時,標簽名與類名康谆、id名進行的組合原理是一樣的沃暗,例如查找 p 標簽中,id 等于 link1的內(nèi)容忱叭,二者需要用空格分開
print soup.select('p #link1')
#[<a class="sister"  id="link1"><!-- Elsie --></a>]
  • 直接子標簽查找韵丑,則使用 > 分隔
print soup.select("head > title")
#[<title>The Dormouse's story</title>]
(5)屬性查找
  • 查找時還可以加入屬性元素,屬性需要用中括號括起來陌僵,注意屬性和標簽屬于同一節(jié)點碗短,所以中間不能加空格偎谁,否則會無法匹配到巡雨。
print(soup.select('a[class="sister"]'))
#[<a class="sister"  id="link1"><!-- Elsie --></a>, <a class="sister"  id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

print (soup.select('a[))
#[<a class="sister"  id="link1"><!-- Elsie --></a>]
同樣,屬性仍然可以與上述查找方式組合正蛙,不在同一節(jié)點的空格隔開咽筋,同一節(jié)點的不加空格

print (soup.select('p a[))

#[<a class="sister"  id="link1"><!-- Elsie --></a>]
(6) 獲取內(nèi)容
  • 以上的 select 方法返回的結(jié)果都是列表形式奸攻,可以遍歷形式輸出睹耐,然后用 get_text() 方法來獲取它的內(nèi)容。
soup = BeautifulSoup(html, 'lxml')
print (type(soup.select('title')))
print (soup.select('title')[0].get_text())

for title in soup.select('title'):
    print (title.get_text())
result = BeautifulSoup(response.text,'lxml')
# print(result)
tr = result.select('a')
# print(tr)
for i in tr:
    print(i["href"])#獲取href屬性
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子假哎,更是在濱河造成了極大的恐慌,老刑警劉巖惧蛹,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機徽千,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铐维,“玉大人嫁蛇,你說我怎么就攤上這事∫值常” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我严衬,道長请琳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮踱讨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帚稠。我一直安慰自己,他們只是感情好馆衔,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布减细。 她就那樣靜靜地躺著未蝌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狰腌,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天蹋笼,我揣著相機與錄音,去河邊找鬼擂达。 笑死究恤,一個胖子當著我的面吹牛部宿,可吹牛的內(nèi)容都是我干的赫蛇。 我是一名探鬼主播织狐,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼起意,長吁一口氣:“原來是場噩夢啊……” “哼揽咕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顿肺,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤托享,失蹤者是張志新(化名)和其女友劉穎浸赫,沒想到半個月后闰围,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡既峡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年羡榴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片运敢。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡校仑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出者冤,到底是詐尸還是另有隱情肤视,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布涉枫,位于F島的核電站邢滑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏愿汰。R本人自食惡果不足惜困后,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望衬廷。 院中可真熱鬧摇予,春花似錦、人聲如沸吗跋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跌宛。三九已至酗宋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疆拘,已是汗流浹背蜕猫。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哎迄,地道東北人回右。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓隆圆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親翔烁。 傳聞我的和親對象是個殘疾皇子渺氧,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

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

  • 以"#"開頭的行就是注釋,會被解釋器忽略租漂。 sh里沒有多行注釋阶女,只能每一行加一個#號颊糜。 如果在開發(fā)過程中哩治,遇到大段...
    frankisbaby閱讀 296評論 0 0
  • 拍到一定程度的大師級攝影師看重的是照片傳達的情感,動作只是輔助衬鱼。 而對于攝影初學者來說业筏,沒有瀏覽過太多的照片,還無...
    芥茉在拍照閱讀 3,095評論 7 41