【相關推薦:Python3視訊教學 】
Beautiful Soup 是一個可以從HTML或XML檔案中提取資料的Python庫.它能夠通過你喜歡的轉換器實現慣用的檔案導航,查詢,修改檔案的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間。
BeautifulSoup4將網頁轉換為一顆DOM樹:
1. window電腦點選win鍵+ R
,輸入:cmd
2. 安裝beautifulsoup4
,輸入對應的pip命令:pip install beautifulsoup4
,我已經安裝過了出現版本就安裝成功了
3. 導包
form bs4 import BeautifulSoup
BeautifulSoup在解析時實際上依賴解析器,它除了支援Python標準庫中的HTML解析器外,還支援一 些第三方解析器(比如lxml):
解析器 | 使用方法 | 優勢 | 劣勢 |
---|---|---|---|
Python標準庫 | BeautifulSoup(html,’html.parser’) | Python的內建標準庫、執行速度適中、檔案容錯能力強 | Python 2.7.3及Python3.2.2之前的版本檔案容錯能力差 |
lxml HTML解析庫 | BeautifulSoup(html,’lxml’) | 速度快、檔案容錯能力強 | 需要安裝C語言庫 |
lxml XML解析庫 | BeautifulSoup(html,‘xml' | 速度快、唯一支援XML的解析器 | 需要安裝C語言庫 |
htm5lib解析庫 | BeautifulSoup(html,’htm5llib’) | 最好的容錯性、以瀏覽器的方式解析檔案、生成HTMLS格式的檔案 | 速度慢、不依賴外部擴充套件 |
對於我們來說,我們最常使用的解析器是lxml HTML
解析器,其次是html5lib.
1. 讀取HTML字串:
from bs4 import BeautifulSoup html = ''' <p class="panel"> <p class="panel-heading"> <h4>Hello</h4> </p> <p class="panel_body"> <ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul> <ul class="list list-small" id="list-2"> <li class="element">Foo</li> <a href="https://www.baidu.com">百度官網</a> <li class="element">Bar</li> </ul> </p> </p> '''# 建立物件soup = BeautifulSoup(html, 'lxml')
2. 讀取HTML檔案:
from bs4 import BeautifulSoup soup = BeautifulSoup(open('index.html'),'lxml')
3. 基本方法
from bs4 import BeautifulSoup html = ''' <p class="panel"> <p class="panel-heading"> <h4>Hello</h4> </p> <p class="panel_body"> <ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul> <ul class="list list-small" id="list-2"> <li class="element">Foo</li> <a href="https://www.baidu.com">百度官網</a> <li class="element">Bar</li> </ul> </p> </p> '''# 建立物件soup = BeautifulSoup(html, 'lxml')# 縮排格式print(soup.prettify())# 獲取title標籤的所有內容print(soup.title)# 獲取title標籤的名稱print(soup.title.name)# 獲取title標籤的文字內容print(soup.title.string)# 獲取head標籤的所有內容print(soup.head)# 獲取第一個p標籤中的所有內容print(soup.p)# 獲取第一個p標籤的id的值print(soup.p["id"])# 獲取第一個a標籤中的所有內容print(soup.a)# 獲取所有的a標籤中的所有內容print(soup.find_all("a"))# 獲取id="u1"print(soup.find(id="u1"))# 獲取所有的a標籤,並遍歷列印a標籤中的href的值for item in soup.find_all("a"): print(item.get("href"))# 獲取所有的a標籤,並遍歷列印a標籤的文字值for item in soup.find_all("a"): print(item.get_text())
Beautiful Soup將複雜HTML檔案轉換成一個複雜的樹形結構,每個節點都是Python物件,所有物件可以歸納為4種: Tag , NavigableString , BeautifulSoup , Comment .
(1)Tag:Tag通俗點講就是HTML中的一個個標籤,例如:
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>','lxml') tag = soup.b print(tag) print(type(tag))
輸出結果:
<b class="boldest">Extremely bold</b> <class 'bs4.element.Tag'>
Tag有很多方法和屬性,在 遍歷檔案樹 和 搜尋檔案樹 中有詳細解釋.現在介紹一下tag中最重要的屬性: name
和attributes
:
name屬性:
print(tag.name) # 輸出結果:b # 如果改變了tag的name,那將影響所有通過當前Beautiful Soup物件生成的HTML檔案: tag.name = "b1" print(tag) # 輸出結果:<b1 class="boldest">Extremely bold</b1>
Attributes屬性:
# 取clas屬性 print(tag['class']) # 直接」點」取屬性, 比如: .attrs : print(tag.attrs)
tag 的屬性可以被新增、修改和刪除:
# 新增 id 屬性 tag['id'] = 1 # 修改 class 屬性 tag['class'] = 'tl1' # 刪除 class 屬性 del tag['class']
(2)NavigableString:用.string
獲取標籤內部的文字:
print(soup.b.string)print(type(soup.b.string))
(3)BeautifulSoup:表示的是一個檔案的內容,可以獲取它的型別,名稱,以及屬性:
print(type(soup.name)) # <type 'unicode'> print(soup.name) # [document] print(soup.attrs) # 檔案本身的屬性為空
(4)Comment:是一個特殊型別的 NavigableString 物件,其輸出的內容不包括註釋符號。
print(soup.b) print(soup.b.string) print(type(soup.b.string))
1.find_all(name, attrs, recursive, text, **kwargs)
(1)name 引數:name 引數可以查詢所有名字為 name 的tag,字串物件會被自動忽略掉
匹配字串:查詢與字串完整匹配的內容,用於查詢檔案中所有的<a>
標籤
a_list = soup.find_all("a")print(a_list)
匹配正規表示式:如果傳入正規表示式作為引數,Beautiful Soup會通過正規表示式的 match() 來匹配內容
# 返回所有表示<body>和<b>標籤for tag in soup.find_all(re.compile("^b")): print(tag.name)
匹配列表:如果傳入列表引數,Beautiful Soup會將與列表中任一元素匹配的內容返回
# 返回所有所有<p>標籤和<a>標籤:soup.find_all(["p", "a"])
(2)kwargs引數
soup.find_all(id='link2')
(3)text引數:通過 text 引數可以搜搜檔案中的字串內容,與 name 引數的可選值一樣, text 引數接受 字串 , 正規表示式 , 列表
# 匹配字串 soup.find_all(text="a") # 匹配正則 soup.find_all(text=re.compile("^b")) # 匹配列表 soup.find_all(text=["p", "a"])
我們在使用BeautifulSoup解析庫時,經常會結合CSS選擇器來提取資料。
注意:以下講解CSS選擇器只選擇標籤,至於獲取屬性值和文字內容我們後面再講。
1. 根據標籤名查詢:比如寫一個 li
就會選擇所有li 標籤
, 不過我們一般不用,因為我們都是精確到標籤再提取資料的
from bs4 import BeautifulSoup html = ''' <p class="panel"> <p class="panel-heading"> <h4>Hello</h4> </p> <p class="panel_body"> <ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul> <ul class="list list-small" id="list-2"> <li class="element">Foo</li> <a href="https://www.baidu.com">百度官網</a> <li class="element">Bar</li> </ul> </p> </p> '''# 建立物件soup = BeautifulSoup(html, 'lxml')# 1. 根據標籤名查詢:查詢li標籤print(soup.select("li"))
輸出結果:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
2. 根據類名class查詢。.1ine
, 即一個點加line,這個表示式選的是class= "line "
的所有標籤,".」
代表class
print(soup.select(".panel_body"))
輸出結果:
</ul> <ul class="list list-small" id="list-2"> <li class="element">Foo</li> <li class="element">Bar</li> </ul> </div>]
3. 根據id查詢。#box,即一個#和box表示選取id-」box "的所有標籤,「#」代表id
print(soup.select("#list-1"))
輸出結果:
[<ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul>]
4. 根據屬性的名字查詢。class屬性和id屬性較為特殊,故單獨拿出來定義一個". "
和「」
來表示他們。
比如:input[ name=「username」]這個表示式查詢name= "username "的標籤,此處注意和xpath語法的區別
print(soup.select('ul[ name="element"]'))
輸出結果:
[<ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul>]
5. 標籤+類名或id的形式。
# 查詢id為list-1的ul標籤 print(soup.select('ul#list-1')) print("-"*20) # 查詢class為list的ul標籤 print(soup.select('ul.list'))
輸出結果:
[<ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul>] -------------------- [<ul class="list" id="list-1" name="element"> <li class="element">Foo</li> <li class="element">Bar</li> <li class="element">Jay</li> </ul>, <ul class="list list-small" id="list-2"> <li class="element">Foo</li> <li class="element">Bar</li> </ul>]
6. 查詢直接子元素
# 查詢id="list-1"的標籤下的直接子標籤liprint(soup.select('#list-1>li'))
輸出結果:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
7. 查詢子孫標籤
# .panel_body和li之間是一個空格,這個表示式查詢id=」.panel_body」的標籤下的子或孫標籤liprint(soup.select('.panel_body li'))
輸出結果:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
8. 取某個標籤的屬性
# 1. 先取到<p class="panel_body">p = soup.select(".panel_body")[0]# 2. 再去下面的a標籤下的href屬性print(p.select('a')[0]["href"])
輸出結果:
https://www.baidu.com
9. 獲取文字內容有四種方式:
(a) string
:獲得某個標籤下的文字內容,強調-一個標籤,不含嵌我。 返回-個字串
# 1. 先取到<p class="panel_body">p = soup.select(".panel_body")[0]# 2. 再去下面的a標籤下print(p.select('a')[0].string)
輸出結果:
百度官網
(b) strings
:獲得某個標籤下的所有文字內容,可以巢狀。返回-一個生成器,可用list(生成器)轉換為列表
print(p.strings)print(list(p.strings))
輸出結果:
<generator object Tag._all_strings at 0x000001AA58E525F0>['\n', '\n', 'Foo', '\n', 'Bar', '\n', 'Jay', '\n', '\n', '\n', 'Foo', '\n', '百度官網', '\n', 'Bar', '\n', '\n']
(c)stripped.strings
:跟(b)差不多,只不過它會去掉每個字串頭部和尾部的空格和換行符
print(p.stripped_strings)print(list(p.stripped_strings))
輸出結果:
<generator object PageElement.stripped_strings at 0x000001F9995525F0>['Foo', 'Bar', 'Jay', 'Foo', '百度官網', 'Bar']
(d) get.text()
:獲取所有字串,含巢狀. 不過會把所有字串拼接為一個,然後返回
注意2:
前3個都是屬性,不加括號;最後一個是函數,加括號。
print(p.get_text())
輸出結果:
Foo Bar Jay Foo 百度官網 Bar
【相關推薦:Python3視訊教學 】
以上就是一文搞懂Python爬蟲解析器BeautifulSoup4的詳細內容,更多請關注TW511.COM其它相關文章!