介紹
BeautifulSoup和pyquery都是用來解析html的庫,與昨天學的XPath有很多相似之處,因此就將這兩個庫放在一起學習
BeautifulSoup庫
基本用法
from bs4 import BeautifulSoup
html = #略
# 初始化BeautifulSoup,第二個參數表示解釋器為lxml
soup = BeautifulSoup(html, 'lxml')
# prettify()方法可以標准化html的縮進格式
print(soup.prettify())
#
節點選擇器
直接調用節點的名稱就可以選擇節點元素,例如soup.div就是選擇第一個div節點
經過選擇器選擇后,選擇結果都是bs4.element.Tag類型,這是這個庫里一個重要的數據結構
Tag類型同樣可以繼續調用節點進行下一步的選擇,例如soup.div.ul,也就是說可以嵌套選擇,選擇后的結果依然是Tag類型
關於Tag類,有幾個常用的屬性介紹一下
# 節點的文本內容
soup.div.string
# 節點的名稱
soup.div.name
# 節點的屬性
soup.div.attrs
其中string和name都是str類型,而attrs是dict類型,因為節點可能會有多個屬性。
屬性的類型也不一定都是str類型,有的返回結果是字符串組成的列表,例如class屬性,一個節點元素可能有多個class。
此外,再介紹一下如何選中關聯節點。
# 子節點,返回結果是列表形式,包含節點和文本
soup.p.contents
# 子節點,返回結果是生成器,需要遍歷輸出
soup.p.children
# 子孫節點,返回結果是生成器,需要遍歷輸出
soup.p.descendants
# 父節點
soup.p.parent
# 祖先節點
soup.p.parents
# 兄弟節點
## 后一個兄弟節點
soup.p.next_sibling
## 后面的所有兄弟節點
soup.p.next_siblings
## 前一個兄弟節點
soup.p.previous_sibling
## 前面的所有兄弟節點
soup.p.previous_siblings
這些關聯節點返回不全是Tag類型,但是有相同的屬性,所以可以用相同的方式查詢屬性
方法選擇器
- find_all()
這個方法的API如下:find_all(name, attrs, recursive, text, **kwargs)
第一個屬性是節點名,返回結果是列表類型,其元素是Tag類型
第二個是屬性,返回結果是列表類型,其元素是Tag類型
第三個是文本,傳入類型可以是字符串,也可以是正則表達式對象,返回結果是列表類型,其元素是str類型 - find()
返回單個元素,其余類似find_all()方法 - find_parents()和find_parent()
- find_next_siblings()和find_next_sibling()
- find_previous_siblings()和find_previous_sibling()
pyquery庫
關於BeautifulSoup,其實還有CSS選擇器部分沒介紹,但是pyquery的CSS選擇器更加強大,因此就直接介紹pyquery吧
初始化
類似於bs,初始化pyquery的時候,也需要傳入HTML來初始化一個PyQuery對象。它的初始化方式有多種,可以直接傳入字符串,可以傳入URL,可以傳入HTML文件等
from pyquery import PyQuery as pq
doc = pq(html)
doc = pq(url='https://cuiqingcai.com')
doc = pq(filename='deme.html')
查找節點
# 選取class為list的節點
items = doc('.list')
# 子節點
lis = items.children()
# class為active的子節點
lis = items.children('.active')
# 傳入CSS選擇器,選取為li的子孫節點
lis = items.find('li')
# 父節點
lis = items.parent()
# 祖先節點,如果需要篩選,也可以傳入CSS選擇器
container = items.parents()
# 兄弟節點
lis = ltems.siblings()
遍歷
pyquery的選擇結果可能是多個節點,類型都是PyQuery類型,所以需要遍歷來獲取。這時候需要調用item()方法
lis = doc('li').item()
for li in lis:
print(li)
獲取信息
類似於bs,這里用attrs()來獲取屬性,用text()來獲取文本
但如果想獲取HTML文本,需要調用html()方法
節點操作
pyquery提供了一系列方法來對節點進行動態修改,這里就介紹一些常用的方法
li = doc('item-0.active')
# 刪除class屬性
li.removeClass('active')
# 添加class屬性
li.addClass('active')
# 改變屬性
li.attr('name', 'link')
# 改變文本內容
li.text(str)
# 改變html
li.html(html)
# 移除節點
li.remove()
偽類選擇器
# 第一個li節點
li = doc('li:first-hild')
# 最后一個li節點
li = doc('li:last-child')
# 第二個li節點
li = doc('li:nth-child(2)')
# 第三個li之后的li節點
li = doc('li:gt(2)')
# 偶數位置的li節點
li = doc('li:nth-child(2n)')
# 包含second文本的li節點
li = doc('li:contains(second)')
總結
關於HTML解析庫的內容,基本上就全部介紹完了,通過這些內容,基本可以解決HTML的解析了。
接下來打算跳過書本的第五章,直接學習ajax的有關內容,因為接下來打算做一個和淘寶有關的項目,需要了解動態加載的內容。