BeautifulSoup就是Python的一個HTML或XML的解析庫,可以用它來方便地從網頁中提取數據。官方解釋如下:
Beautiful Soup提供一些簡單的、Python式的函數來處理導航、搜索、修改分析樹等功能。它是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,因為簡單,所以不需要多少代碼就可以寫出一個完整的應用程序。
Beautiful Soup自動將輸入文檔轉換為Unicode編碼,輸出文檔轉換為UTF-8編碼。你不需要考慮編碼方式,除非文檔沒有指定一個編碼方式,這時你僅僅需要說明一下原始編碼方式就可以了。
Beautiful Soup已成為和lxml、html6lib一樣出色的Python解釋器,為用戶靈活地提供不同的解析策略或強勁的速度。
所以說,利用它可以省去很多煩瑣的提取工作,提高了解析效率。
一、模塊安裝
使用之前,需要確保已經安裝好了BeautifulSoup和lxml模塊。
pip install beautifulsoup4 lxml
二、解析器選擇
Beautiful Soup在解析時實際上依賴解析器,它除了支持Python標准庫中的HTML解析器外,還支持一些第三方解析器(比如lxml)。下表為BeautifulSoup支持的解析器:
| 解析器 |
使用方法 |
優勢 |
劣勢 |
|---|---|---|---|
| Python標准庫 |
|
Python的內置標准庫、執行速度適中、文檔容錯能力強 |
Python 2.7.3及Python 3.2.2之前的版本文檔容錯能力差 |
| lxml HTML解析器 |
|
速度快、文檔容錯能力強 |
需要安裝C語言庫 |
| lxml XML解析器 |
|
速度快、唯一支持XML的解析器 |
需要安裝C語言庫 |
| html5lib |
|
最好的容錯性、以瀏覽器的方式解析文檔、生成HTML5格式的文檔 |
速度慢、不依賴外部擴展 |
通過以上對比可以看出,lxml解析器有解析HTML和XML的功能,而且速度快,容錯能力強,所以推薦使用它。
如果使用lxml,那么在初始化Beautiful Soup時,可以把第二個參數改為lxml即可:
from bs4 import BeautifulSoup soup = BeautifulSoup('<p>Hello</p>', 'lxml') print(soup.p.string)
三、基本用法
from bs4 import BeautifulSoup import requests, re req_obj = requests.get('https://www.baidu.com') soup = BeautifulSoup(req_obj.text, 'lxml') '''標簽查找''' print(soup.title) # 只是查找出第一個 print(soup.find('title')) # 效果和上面一樣 print(soup.find_all('div')) # 查出所有的div標簽 '''獲取標簽里的屬性''' tag = soup.div print(tag['class']) # 多屬性的話,會返回一個列表 print(tag['id']) # 查找標簽的id屬性 print(tag.attrs) # 查找標簽所有的屬性,返回一個字典(屬性名:屬性值) '''標簽包的字符串''' tag = soup.title print(tag.string) # 獲取標簽里的字符串 tag.string.replace_with("哈哈") # 字符串不能直接編輯,可以替換 '''子節點的操作''' tag = soup.head print(tag.title) # 獲取head標簽后再獲取它包含的子標簽 '''contents 和 .children''' tag = soup.body print(tag.contents) # 將標簽的子節點以列表返回 print([child for child in tag.children]) # 輸出和上面一樣 '''descendants''' tag = soup.body [print(child_tag) for child_tag in tag.descendants] # 獲取所有子節點和子子節點 '''strings和.stripped_strings''' tag = soup.body [print(str) for str in tag.strings] # 輸出所有所有文本內容 [print(str) for str in tag.stripped_strings] # 輸出所有所有文本內容,去除空格或空行 '''.parent和.parents''' tag = soup.title print(tag.parent) # 輸出便簽的父標簽 [print(parent) for parent in tag.parents] # 輸出所有的父標簽 '''.next_siblings 和 .previous_siblings 查出所有的兄弟節點 ''' '''.next_element 和 .previous_element 下一個兄弟節點 ''' '''find_all的keyword 參數''' soup.find_all(id='link2') # 查找所有包含 id 屬性的標簽 soup.find_all(href=re.compile("elsie")) # href 參數,Beautiful Soup會搜索每個標簽的href屬性: soup.find_all(id=True) # 找出所有的有id屬性的標簽 soup.find_all(href=re.compile("elsie"), id='link1') # 也可以組合查找 soup.find_all(attrs={"屬性名": "屬性值"}) # 也可以通過字典的方式查找
更多詳細使用可參考:https://cuiqingcai.com/5548.html
