此文檔是根據(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")