Python?BeautifulSoup4實現數據解析與提取
Beautiful Soup4
概述
Beautiful Soup是一個Python的庫,用于解析HTML和XML文檔,提供了方便的數據提取和操作功能。它可以幫助從網頁中提取所需的數據,例如標簽、文本內容、屬性等。
Beautiful Soup會自動將輸入文檔轉換為Unicode編碼,輸出文檔轉換為utf-8編碼。
Beautiful Soup用來解析 HTML比較簡單,API非常人性化,支持多種解析器。
文檔:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/
文檔:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
主要特點
靈活的解析方式:
Beautiful Soup支持多種解析器,包括Python標準庫中的html.parser解析器,以及第三方庫lxml和html5lib。這樣,我們可以根據需要選擇合適的解析器進行處理。
簡單直觀的API:
Beautiful Soup提供了簡潔而友好的API,使得解析HTML文檔變得非常容易。我們可以使用簡潔的方法來選擇特定的標簽、獲取標簽中的文本內容、提取屬性值等。
強大的文檔遍歷能力:
通過Beautiful Soup,我們可以遍歷整個HTML文檔樹,訪問、修改或刪除各個節(jié)點,甚至可以通過嵌套選擇器,快速地定位到需要的節(jié)點。
對破碎HTML的容錯處理:
Beautiful Soup能夠處理破碎的HTML文檔,例如自動糾正未閉合的標簽、自動添加缺失的標簽等,使得提取數據更加穩(wěn)定和可靠。
解析器
Beautiful在解析時依賴解析器,它除了支持Python標準庫中的HTML解析器外,還支持一些第三方庫。
支持的解析器:
解析器 | 使用方法 | 優(yōu)勢 | 劣勢 |
---|---|---|---|
Python標準庫 | BeautifulSoup(markup, "html.parser") | Python的內置標準庫 執(zhí)行速度適中 文檔容錯能力強 | Python 2.7.3 or 3.2.2)前 的版本中文檔容錯能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快 文檔容錯能力強 | 需要安裝C語言庫 |
lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"]) BeautifulSoup(markup, "xml") | 速度快 唯一支持XML的解析器 | 需要安裝C語言庫 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容錯性 以瀏覽器的方式解析文檔 生成HTML5格式的文檔 | 速度慢 不依賴外部擴展 |
由此可見:
lxml解析器可以解析HTML和XML文檔,并且速度快,容錯能力強,所有推薦使用它。如果使用lxml,那么在初始化的BeautifulSoup時候,把第二個參數設為lxml即可。
Beautiful Soup4的基本使用
安裝庫
pip install beautifulsoup4 pip install lxml
創(chuàng)建HTML文件
將一段文檔傳入BeautifulSoup 的構造方法,就能得到一個文檔的對象, 可以傳入一段字符串或一個文件。
這里創(chuàng)建一個test.html
文件,以此創(chuàng)建一個文檔對象。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <ul> <li class="class01"><span index="1">H1</span></li> <li class="class02"><span index="2" class="span2">H2</span></li> <li class="class03"><span index="3">H3</span></li> </ul> </div> </body> </html>
基本用法
# 導入模塊 from bs4 import BeautifulSoup # 創(chuàng)建 beautifulsoup對象,有2種方式創(chuàng)建 # 1.通過字符串創(chuàng)建, 第二個參數用于指定解析器 # soup = BeautifulSoup("html", 'lxml') # 2.通過文件創(chuàng)建 soup = BeautifulSoup(open('test.html'), 'lxml') # 打印輸出 # print(soup.prettify()) # 獲取元素標簽元素,默認返回第一個元素 print(soup.li) # 使用 .contents 或 .children 獲取子元素 # 返回列表 print(soup.ul.contents) # 返回迭代器 print(soup.li.children) # 獲取元素內容 print(soup.title.get_text()) # 獲取元素屬性值,默認取第一個元素屬性值 print(soup.li.get('class'))
操作結果如下:
<li class="class01"><span index="1">H1</span></li>
['\n', <li class="class01"><span index="1">H1</span></li>, '\n', <li class="class02"><span class="span2"
index="2">H2</span></li>, '\n', <li class="class03"><span index="3">H3</span></li>, '\n']
<list_iterator object at 0x000001C18E475F10>
Title
['class01']
Beautiful Soup4的對象種類
Beautiful Soup將復雜HTML文檔轉換成一個復雜的樹形結構,每個節(jié)點都是Python對象,所有對象可以歸納為4種: Tag , NavigableString , BeautifulSoup , Comment
Tag對象
在Beautiful Soup中,Tag對象是用于表示HTML或XML文檔中的標簽元素的對象,Tag對象與原生文檔中的tag相同。Tag對象包含了標簽元素的名稱、屬性和內容等信息,并提供了多種方法來獲取、修改和操作這些信息。
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>') tag = soup.b type(tag) # <class 'bs4.element.Tag'>
常用的Tag對象的屬性和方法
屬性 | 描述 | 示例 |
---|---|---|
name屬性 | 獲取標簽的名稱 | tag_name = tag.name |
string屬性 | 獲取標簽內的文本內容 | tag_text = tag.string |
attrs屬性 | 獲取標簽的屬性,以字典的形式返回 | tag_attrs = tag.attrs |
get()方法 | 根據屬性名獲取標簽的屬性值 | attr_value = tag.get('attribute_name') |
find()方法 | 查找并返回第一個滿足條件的子標簽元素 | child_tag = tag.find('tag_name') |
find_all()方法 | 查找并返回所有滿足條件的子標簽元素,以列表的形式返回 | child_tags = tag.find_all('tag_name') |
parent屬性 | 獲取當前標簽的父標簽 | parent_tag = tag.parent |
parents屬性 | 獲取當前標簽的所有祖先標簽,以生成器的形式返回 | for parent in tag.parents: print(parent) |
children屬性 | 獲取當前標簽的直接子標簽,以生成器的形式返回 | for child in tag.children: print(child) |
next_sibling屬性 | 獲取當前標簽的下一個兄弟標簽 | next_sibling_tag = tag.next_sibling |
previous_sibling屬性 | 獲取當前標簽的上一個兄弟標簽 | previous_sibling_tag = tag.previous_sibling |
NavigableString對象
NavigableString對象是Beautiful Soup庫中的一種數據類型,用于表示在HTML或XML文檔中的純文本內容。它繼承自Python的基本字符串類型,但具有額外的功能和特性,使其適用于處理文檔中的文本內容。
假設有如下HTML代碼片段:
<p>This is a <b>beautiful</b> day.</p>
使用Beautiful Soup將其解析為一個文檔對象:
from bs4 import BeautifulSoup html = '<p>This is a <b>beautiful</b> day.</p>' soup = BeautifulSoup(html, 'html.parser')
獲取
標簽的內容,這實際上是一個NavigableString對象:
p_tag = soup.find('p') content = p_tag.string print(content) # 輸出:This is a print(type(content)) # 輸出:<class 'bs4.element.NavigableString'>
還可以對NavigableString對象進行一些操作,如獲取文本內容、替換文本以及去除空白字符:
# 獲取文本內容 text = content.strip() print(text) # 輸出:This is a # 替換文本 p_tag.string.replace_with('Hello') print(p_tag) # 輸出:<p>Hello<b>beautiful</b> day.</p> # 去除空白字符 text_without_spaces = p_tag.string.strip() print(text_without_spaces) # 輸出:Hello
屬性 | 描述 | 示例 |
---|---|---|
string屬性 | 用于獲取NavigableString對象的文本內容 | text = navigable_string.string |
replace_with()方法 | 用于用另一個字符串或對象替換當前NavigableString對象 | navigable_string.replace_with(new_string) |
strip()方法 | 去除字符串兩端的空白字符 | stripped_text = navigable_string.strip() |
parent屬性 | 獲取NavigableString對象所屬的父節(jié)點(通常是一個Tag對象) | parent_tag = navigable_string.parent |
next_sibling屬性 | 獲取NavigableString對象的下一個兄弟節(jié)點 | next_sibling = navigable_string.next_sibling |
previous_sibling屬性 | 獲取NavigableString對象的上一個兄弟節(jié)點 | previous_sibling = navigable_string.previous_sibling |
BeautifulSoup對象
BeautifulSoup對象是Beautiful Soup庫的核心對象,用于解析和遍歷HTML或XML文檔。
常用方法:
find(name, attrs, recursive, string, **kwargs):根據指定的標簽名、屬性、文本內容等查找第一個匹配的標簽
find_all(name, attrs, recursive, string, limit, **kwargs): 根據指定的標簽名、屬性、文本內容等查找所有匹配的標簽,并返回一個列表
select(css_selector): 使用CSS選擇器語法查找匹配的標簽,并返回一個列表
prettify():以美觀的方式輸出整個文檔的內容,包括標簽、文本和縮進
has_attr(name):檢查當前標簽是否具有指定的屬性名,返回布爾值
get_text():獲取當前標簽和所有子標簽的文本內容,并返回一個字符串
常用屬性:
soup.title:獲取文檔中第一個<title>標簽的內容
soup.head:獲取文檔中的<head>標簽
soup.body:獲取文檔中的<body>標簽
soup.find_all('tag'):獲取文檔中所有匹配的<tag>標簽,并返回一個列表
soup.text:獲取整個文檔中的純文本內容(去除標簽等)
Comment對象
Comment對象是Beautiful Soup庫中的一種特殊類型的對象,用于表示HTML或XML文檔中的注釋內容。
在解析HTML或XML文檔時,Beautiful Soup將注釋內容作為Comment對象來表示。注釋是文檔中的一種特殊元素,用于添加注解、說明或暫時刪除一部分內容。Comment對象可以通過Beautiful Soup庫的解析器自動識別和處理。
處理和訪問HTML文檔中的注釋內容示例:
from bs4 import BeautifulSoup # 創(chuàng)建包含注釋的HTML字符串 html = "<html><body><!-- This is a comment --> <p>Hello, World!</p></body></html>" # 解析HTML文檔 soup = BeautifulSoup(html, 'html.parser') # 使用type()函數獲取注釋對象的類型 comment = soup.body.next_sibling print(type(comment)) # 輸出 <class 'bs4.element.Comment'> # 使用`.string`屬性獲取注釋內容 comment_content = comment.string print(comment_content) # 輸出 This is a comment
搜索文檔樹
Beautiful Soup提供了多種方式來查找和定位HTML文檔中的元素。
方法選擇器
使用Beautiful Soup的find()或find_all()方法可以通過標簽名、結合屬性名和屬性值、結合文本內容等方式來選擇元素。
兩者區(qū)別:
find返回符合條件的第一個元素
find_all返回符合條件的所有元素列表
例如:soup.find('div')
會返回第一個div標簽的元素,soup.find_all('a')
會返回所有的a標簽元素。
1.通過標簽或標簽列表查找元素
# 查找第一個div標簽的元素 soup.find('div') # 查找所有的a標簽元素 soup.find_all('a') # 查找所有l(wèi)i標簽 soup.find_all('li') # 查找所有a標簽和b標簽 soup.find_all(['a','b'])
2.通過正則表達式查找元素
# 以sp開頭的標簽查找 import re print(soup.find_all(re.compile("^sp")))
3.通過屬性查找元素
find = soup.find_all( attrs={ "屬性名":"值" } ) print(find)
# 查找第一個具有href屬性的a標簽元素 soup.find('a', href=True) # 查找所有具有class屬性的div標簽元素 soup.find_all('div', class_=True)
4.通過文本內容查找元素
# 查找第一個包含"Hello"文本內容的元素 soup.find(text='Hello') # 查找所有包含"World"文本內容的元素 soup.find_all(text="World")
5.通過關鍵詞參數查找元素
soup.find_all(id='id01')
6.混合使用
soup.find_all( '標簽名', attrs={ "屬性名":"值" }, text="內容" )
CSS選擇器
使用Beautiful Soup的select()方法可以通過CSS選擇器來查找元素。CSS選擇器是一種強大而靈活的方式,可以根據標簽名、類名、ID、屬性以及它們的組合來定位元素。
1.類選擇器
通過類名查找元素,使用.
符號加上類名來查找元素
soup.select('.className')
2.ID選擇器
通過ID查找元素,使用#
符號加上ID來查找元素
soup.select('#id')
3.標簽選擇器
通過標簽名查找元素,直接使用標簽名來查找元素
soup.select('p')
4.屬性選擇器
通過屬性查找元素:可以使用[屬性名=屬性值]
的格式來查找具有特定屬性及屬性值的元素
soup.select('[屬性="值"]') soup.select('[href="example.com"]') soup.select('a[)
5.組合選擇器
可以將多個選擇器組合在一起以獲得更精確的查找
# 返回所有在具有特定類名的div元素內的a標簽元素 soup.select('div.class01 a') soup.select('div a')
關聯選擇
在進行元素查找的過程中,有時候不能做到一步就獲取到想要的節(jié)點元素,需要選取某一個節(jié)點元素,然后以這個節(jié)點為基準再選取它的子節(jié)點、父節(jié)點、兄弟節(jié)點等。
在Beautiful Soup中,可以通過使用CSS選擇器語法來進行關聯選擇,需要借助Beautiful Soup的select()方法,它允許使用CSS選擇器來選擇元素。
1.后代選擇器(空格):可以選擇指定元素下的所有后代元素。
div a /* 選擇div元素下的所有a元素 */
.container p /* 選擇類名為container的元素下的所有p元素 */
2.直接子代選擇器(>):可以選擇指定元素的直接子代元素。
div > a /* 選擇div元素的直接子代的a元素 */
.container > p /* 選擇類名為container的元素的直接子代的p元素 */
3.相鄰兄弟選擇器(+):可以選擇與指定元素緊鄰的下一個同級元素。
h1 + p /* 選擇緊接在h1元素后的同級p元素 */
.container + p /* 選擇緊接在類名為container的元素后的同級p元素 */
4.通用兄弟選擇器(~):可以選擇與指定元素同級的所有后續(xù)元素。
h1 ~ p /* 選擇與h1元素同級的所有p元素 */
.container ~ p /* 選擇與類名為container的元素同級的所有p元素 */
5.混合選擇器:可以結合多個不同類型的選擇器來選擇特定的元素
div , p /* 選擇所有div元素和所有p元素 */
.cls1.cls2 /* 選擇類名是cls1并且類名是cls2 */
遍歷文檔樹
在Beautiful Soup中,遍歷文檔樹是一種常見的操作,用于訪問和處理HTML或XML文檔的各個節(jié)點
標簽的子節(jié)點和父節(jié)點
contents:獲取Tag的所有子節(jié)點,返回一個list
print(bs.tag.contents) # 使用列表索引獲取某一個元素 print(bs.tag.contents[1])
children:獲取Tag的所有子節(jié)點,返回一個生成器
for child in tag.contents: print(child)
parent屬性獲取標簽的父節(jié)點
parent_tag = tag.parent
標簽的同級兄弟節(jié)點
可以使用.next_sibling和.previous_sibling屬性獲取標簽的下一個或上一個同級兄弟節(jié)點。
next_sibling = tag.next_sibling previous_sibling = tag.previous_sibling
遞歸遍歷文檔樹
可以使用.find()和.find_all()方法在文檔樹中遞歸搜索匹配的標簽。
可以使用.descendants生成器迭代器遍歷文檔樹的所有子孫節(jié)點。
for tag in soup.find_all('a'): print(tag) for descendant in tag.descendants: print(descendant)
遍歷標簽屬性
可以使用.attrs屬性獲取標簽的所有屬性,并遍歷它們。
for attr in tag.attrs: print(attr)
以上就是Python BeautifulSoup4實現數據解析與提取的詳細內容,更多關于Python BeautifulSoup4的資料請關注腳本之家其它相關文章!
相關文章
Keras搭建孿生神經網絡Siamese?network比較圖片相似性
這篇文章主要為大家介紹了Keras搭建孿生神經網絡Siamese?network比較圖片相似性,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05