08. 數(shù)據(jù)提取-Beautiful Soup
Beautiful Soup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。你不需要考慮編碼方式,除非文檔沒有指定一個(gè)編碼方式,這時(shí),Beautiful Soup就不能自動(dòng)識(shí)別編碼方式了。然后,你僅僅需要說明一下原始編碼方式就可以了。
Beautiful Soup已成為和lxml、html6lib一樣出色的python解釋器,為用戶靈活地提供不同的解析策略或強(qiáng)勁的速度
http://beautifulsoup.readthedocs.io/zh_CN/latest/
2. Beautiful Soup 安裝
Beautiful Soup 3 目前已經(jīng)停止開發(fā),推薦在現(xiàn)在的項(xiàng)目中使用Beautiful Soup 4,不過它已經(jīng)被移植到BS4了,也就是說導(dǎo)入時(shí)我們需要 import bs4
pip install beautifulsoup4
Beautiful Soup支持Python標(biāo)準(zhǔn)庫(kù)中的HTML解析器,還支持一些第三方的解析器,如果我們不安裝它,則 Python 會(huì)使用 Python默認(rèn)的解析器,lxml 解析器更加強(qiáng)大,速度更快,推薦安裝
解析器使用方法優(yōu)勢(shì)劣勢(shì)Python標(biāo)準(zhǔn)庫(kù)BeautifulSoup(markup, “html.parser”)1. Python的內(nèi)置標(biāo)準(zhǔn)庫(kù) ?2. 執(zhí)行速度適中 3.文檔容錯(cuò)能力強(qiáng)Python 2.7.3 or 3.2.2)前 的版本中文檔容錯(cuò)能力差lxml HTML 解析器BeautifulSoup(markup, “l(fā)xml”)1. 速度快 2.文檔容錯(cuò)能力強(qiáng)需要安裝C語言庫(kù)lxml XML 解析器BeautifulSoup(markup, [“l(fā)xml”, “xml”]) ?BeautifulSoup(markup, “xml”)1. 速度快 2.唯一支持XML的解析器 3.需要安裝C語言庫(kù)html5libBeautifulSoup(markup, “html5lib”)1. 最好的容錯(cuò)性 2.以瀏覽器的方式解析文檔 3.生成HTML5格式的文檔 4.速度慢不依賴外部擴(kuò)展
3. 創(chuàng)建 Beautiful Soup 對(duì)象
from bs4 import BeautifulSoup
bs = BeautifulSoup(html,"lxml")
4. 四大對(duì)象種類
Beautiful Soup將復(fù)雜HTML文檔轉(zhuǎn)換成一個(gè)復(fù)雜的樹形結(jié)構(gòu),每個(gè)節(jié)點(diǎn)都是Python對(duì)象,所有對(duì)象可以歸納為4種:
Tag
NavigableString
BeautifulSoup
Comment
4.1 Tag 是什么?通俗點(diǎn)講就是 HTML 中的一個(gè)個(gè)標(biāo)簽
例如:<div>
<title>
使用方式:
#以以下代碼為例子
<title>尚學(xué)堂</title>
<div float='left'>Welcome to SXT</div>
<div float='right'>
? ?<span>Good Good Study</span>
? ?<a href='www.bjsxt.cn'></a>
? ?<strong><!--沒用--></strong>
</div>
4.1.1 獲取標(biāo)簽
#以lxml方式解析
soup = BeautifulSoup(info, 'lxml')
print(soup.title)
# <title>尚學(xué)堂</title>
注意
相同的標(biāo)簽只能獲取第一個(gè)符合要求的標(biāo)簽
4.1.2 獲取屬性:
#獲取所有屬性
print(soup.title.attrs)
#class='info' float='left'
#獲取單個(gè)屬性的值
print(soup.div.get('class'))
print(soup.div['class'])
print(soup.a['href'])
#info
4.2 NavigableString 獲取內(nèi)容
print(soup.title.string)
print(soup.title.text)
#尚學(xué)堂
4.3 BeautifulSoup
BeautifulSoup 對(duì)象表示的是一個(gè)文檔的全部?jī)?nèi)容.大部分時(shí)候,可以把它當(dāng)作 Tag 對(duì)象,它支持 遍歷文檔樹 和 搜索文檔樹 中描述的大部分的方法.
因?yàn)?BeautifulSoup 對(duì)象并不是真正的HTML或XML的tag,所以它沒有name和attribute屬性.但有時(shí)查看它的 .name 屬性是很方便的,所以 BeautifulSoup 對(duì)象包含了一個(gè)值為 “[document]” 的特殊屬性 .name
print(soup.name)
print(soup.head.name)
# [document]
# head
4.4 Comment
Comment 對(duì)象是一個(gè)特殊類型的 NavigableString 對(duì)象,其實(shí)輸出的內(nèi)容仍然不包括注釋符號(hào),但是如果不好好處理它,可能會(huì)對(duì)我們的文本處理造成意想不到的麻煩
if type(soup.strong.string)==Comment:
? ?print(soup.strong.prettify())
else:
? ?print(soup.strong.string)
5 搜索文檔樹
Beautiful Soup定義了很多搜索方法,這里著重介紹2個(gè): find() 和 find_all() .其它方法的參數(shù)和用法類似,請(qǐng)同學(xué)們舉一反三
5.1 過濾器
介紹 find_all() 方法前,先介紹一下過濾器的類型 ,這些過濾器貫穿整個(gè)搜索的API.過濾器可以被用在tag的name中,節(jié)點(diǎn)的屬性中,字符串中或他們的混合中
5.1.1 字符串
最簡(jiǎn)單的過濾器是字符串.在搜索方法中傳入一個(gè)字符串參數(shù),Beautiful Soup會(huì)查找與字符串完整匹配的內(nèi)容,下面的例子用于查找文檔中所有的<div>標(biāo)簽
#返回所有的div標(biāo)簽
print(soup.find_all('div'))
如果傳入字節(jié)碼參數(shù),Beautiful Soup會(huì)當(dāng)作UTF-8編碼,可以傳入一段Unicode 編碼來避免Beautiful Soup解析編碼出錯(cuò)
5.1.2 正則表達(dá)式
如果傳入正則表達(dá)式作為參數(shù),Beautiful Soup會(huì)通過正則表達(dá)式的 match() 來匹配內(nèi)容
#返回所有的div標(biāo)簽
print (soup.find_all(re.compile("^div")))
5.1.3 列表
如果傳入列表參數(shù),Beautiful Soup會(huì)將與列表中任一元素匹配的內(nèi)容返回
#返回所有匹配到的span a標(biāo)簽
print(soup.find_all(['span','a']))
5.1.4 keyword
如果一個(gè)指定名字的參數(shù)不是搜索內(nèi)置的參數(shù)名,搜索時(shí)會(huì)把該參數(shù)當(dāng)作指定名字tag的屬性來搜索,如果包含一個(gè)名字為 id 的參數(shù),Beautiful Soup會(huì)搜索每個(gè)tag的”id”屬性
#返回id為welcom的標(biāo)簽
print(soup.find_all(id='welcom'))
5.1.4 True
True 可以匹配任何值,下面代碼查找到所有的tag,但是不會(huì)返回字符串節(jié)點(diǎn)
5.1.5 按CSS搜索
按照CSS類名搜索tag的功能非常實(shí)用,但標(biāo)識(shí)CSS類名的關(guān)鍵字 class 在Python中是保留字,使用 class 做參數(shù)會(huì)導(dǎo)致語法錯(cuò)誤.從Beautiful Soup的4.1.1版本開始,可以通過 class_ 參數(shù)搜索有指定CSS類名的tag
# 返回class等于info的div
print(soup.find_all('div',class_='info'))
5.1.6 按屬性的搜索
soup.find_all("div", attrs={"class": "info"})
6. CSS選擇器(擴(kuò)展)
soup.select(參數(shù))
