Beautiful Soup學(xué)習(xí)筆記

開始

首先必須要導(dǎo)入 bs4 庫

from bs4 import BeautifulSoup

我自己常用的兩種解析器

soup = BeautifulSoup(markup, "html.parser")
soup = BeautifulSoup(markup, "lxml")

如果要使用lxml必須先安裝

pip install lxml

四大對象種類

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

Tag

Tag就是HTML中的一個個標(biāo)簽, 例如

<title>The Dormouse's story</title>
<a class="sister"  id="link1">Elsie</a>

驗證一下對象類型

print(type(soup.a))
#<class 'bs4.element.Tag'>

對于Tag, 有兩個重要的屬性, name和attrs

name

例如一個b標(biāo)簽, 那么它的name就是b, 一個p標(biāo)簽的name就是p

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

attrs

attrs是一個字典類型的, 對應(yīng)的是屬性-值, 如print soup.p.attrs,輸出的就是{'class': ['title'], 'name': 'dromouse'}, 當(dāng)然你也可以得到具體的值, 如print(soup.p.attrs['class']),輸出的就是[title]是一個列表的類型,因為一個屬性可能對應(yīng)多個值,當(dāng)然你也可以通過get方法得到屬性的, 如:print(soup.p.get('class')). 還可以直接使用print(soup.p['class'])

print(soup.p.attrs)
#{'class':['title'], 'name':'dromouse'}

get

get方法用于得到標(biāo)簽下的屬性值, 注意這是一個重要的方法, 在許多場合都能用到, 比如你要得到<img src="#">標(biāo)簽下的圖像url, 那么就可以用soup.img.get('src'), 具體解析如下:

print soup.p.get("src")   #得到第一個p標(biāo)簽下的src屬性

單獨獲取某個屬性

print(soup.p['class']
#['title']

也可以像下面這樣

print(soup.p.get('class')
#['title']

或者下面那樣

print(soup.p.attrs['class']
#['title']

find_all()

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

find_all() 方法搜索當(dāng)前tag的所有tag子節(jié)點, 并判斷是否符合過濾器的條件
注意:如果一個指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名, 搜索時會把該參數(shù)當(dāng)作指定名字tag的屬性來搜索, 如果包含一個名字為 id 的參數(shù),Beautiful Soup會搜索每個tag的”id”屬性
find_all() 的返回值是一個Tag組成的列表, 方法調(diào)用非常靈活, 所有的參數(shù)都是可選的, 這里有幾個例子:

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

soup.find_all("p", "title")
# [<p class="title"><b>The Dormouse's story</b></p>]

soup.find_all("a")
# [<a class="sister"  id="link1">Elsie</a>,
#  <a class="sister"  id="link2">Lacie</a>,
#  <a class="sister"  id="link3">Tillie</a>]

soup.find_all(id="link2")
# [<a class="sister"  id="link2">Lacie</a>]

import re
soup.find(text=re.compile("sisters"))
# u'Once upon a time there were three little sisters; and their names were\n'

name 參數(shù)

name 參數(shù)可以查找所有名字為 name 的tag,字符串對象會被自動忽略掉

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

傳字符串

soup.find_all('b')
# [<b>The Dormouse's story</b>]
print soup.find_all('a')
#[<a class="sister"  id="link1"><!-- Elsie --></a>...]

傳正則表達(dá)式

如果傳入正則表達(dá)式作為參數(shù),Beautiful Soup會通過正則表達(dá)式的 match() 來匹配內(nèi)容.下面例子中找出所有以b開頭的標(biāo)簽,這表示<body>和<b>標(biāo)簽都應(yīng)該被找到:
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b

傳列表

如果傳入列表參數(shù),Beautiful Soup會將與列表中任一元素匹配的內(nèi)容返回.下面代碼找到文檔中所有<a>標(biāo)簽和<b>標(biāo)簽:
soup.find_all(["a", "b"])

attrs參數(shù)

find_all()中第二個參數(shù)是標(biāo)簽的class屬性值

soup.find_all("a", class_="sister")

等效于

soup.find_all("p", "sister") # p指定了tag的name, sister指定了所有tag的class屬性如果是'sister'就會被返回

keyword參數(shù)

如果一個指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名,搜索時會把該參數(shù)當(dāng)作指定名字tag的屬性來搜索,如果包含一個名字為 id 的參數(shù), Beautiful Soup會搜索每個tag的”id”屬性

soup.find_all(id='link2')
# [<a class="sister"  id="link2">Lacie</a>]
soup.find_all(href=re.compile("elsie"))
# [<a class="sister"  id="link1">Elsie</a>]

多個指定名字參數(shù)同時過濾tag的多個屬性

soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister"  id="link1">three</a>]

定義一個字典來搜索包含特殊屬性的tag

soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]

text參數(shù)

soup.find_all(text="Elsie")
# 'Elsie'
soup.find_all(text=["Tillie", "Elsie"])
['Elsie', 'Tillie']
soup.find_all(text=re.compile("Dormouse"))
['The Dormouse's story]

find()方法

find( name , attrs , recursive , text , **kwargs )
它與 find_all() 方法唯一的區(qū)別是 find_all() 方法的返回結(jié)果是值包含一個元素的列表,而 find() 方法直接返回結(jié)果

get_text()

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

markup = '<a >\nI linked to <i>example.com</i>\n</a>'
soup = BeautifulSoup(markup)

soup.get_text()
u'\nI linked to example.com\n'
soup.i.get_text()
u'example.com'

可以通過參數(shù)指定tag的文本內(nèi)容的分隔符:

# soup.get_text("|")
u'\nI linked to |example.com|\n'

還可以去除獲得文本內(nèi)容的前后空白:

# soup.get_text("|", strip=True)
u'I linked to|example.com'

或者使用 .stripped_strings 生成器,獲得文本列表后手動處理列表:

[text for text in soup.stripped_strings]
# [u'I linked to', u'example.com']

css選擇器

我們在寫 CSS 時,標(biāo)簽名不加任何修飾,類名前加點,id名前加#,在這里我們也可以利用類似的方法來篩選元素,用到的方法是 soup.select(),返回類型是 list

通過標(biāo)簽名查找

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('.sister')
#[<a class="sister"  id="link1"><!-- Elsie --></a>, <a class="sister"  id="link2">Lacie</a>, <a class="sister"  id="link3">Tillie</a>]

通過id名查找

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

組合查找

學(xué)過css的都知道css選擇器,如p #link1是查找p標(biāo)簽下的id屬性為link1的標(biāo)簽

print soup.select('p #link1')    #查找p標(biāo)簽中內(nèi)容為id屬性為link1的標(biāo)簽
#[<a class="sister"  id="link1"><!-- Elsie --></a>]
print soup.select("head > title")   #直接查找子標(biāo)簽
#[<title>The Dormouse's story</title>]

屬性查找

查找時還可以加入屬性元素,屬性需要用中括號括起來,注意屬性和標(biāo)簽屬于同一節(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>]

以上的 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()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容