python常用第三方庫---BeautifulSoup庫(搬運)
BeautifulSoup4是爬蟲必學的技能。BeautifulSoup最主要的功能是從網頁抓取資料,Beautiful Soup自動將輸入文件轉換為Unicode編碼,輸出文件轉換為utf-8編碼。BeautifulSoup支援Python標準庫中的HTML解析器,還支援一些第三方的解析器,如果我們不安裝它,則 Python 會使用 Python預設的解析器,lxml 解析器更加強大,速度更快,推薦使用lxml 解析器。
一、簡介
靈活又方便的網頁解析庫,處理高效,支援多種解析器。
利用它不用編寫正則表示式即可方便地實現網頁資訊的提取。
安裝:pip3 install BeautifulSoup4
解析器 | 使用方法 | 優勢 | 劣勢 |
---|---|---|---|
Python標準庫 | BeautifulSoup(markup, “html.parser”) | Python的內建標準庫、執行速度適中 、文件容錯能力強 | Python 2.7.3 or 3.2.2)前的版本中文容錯能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快、文件容錯能力強 | 需要安裝C語言庫 |
lxml XML 解析器 | BeautifulSoup(markup, “xml”) | 速度快、唯一支援XML的解析器 | 需要安裝C語言庫 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容錯性、以瀏覽器的方式解析文件、生成HTML5格式的文件 | 速度慢、不依賴外部擴充套件 |
二、基本用法
#基本用法 from bs4 import BeautifulSoup bs = BeautifulSoup(html,"html.parser") # 縮排格式 print(bs.prettify()) print(bs.prettify()) # 格式化html結構 print(bs.title) # 獲取title標籤的名稱 print(bs.title.name) # 獲取title的name print(bs.title.string) # 獲取head標籤的所有內容 print(bs.head) print(bs.div) # 獲取第一個div標籤中的所有內容 print(bs.div["id"]) # 獲取第一個div標籤的id的值 print(bs.a) print(bs.find_all("a")) # 獲取所有的a標籤 print(bs.find(id="u1")) # 獲取id="u1" for item in bs.find_all("a"): print(item.get("href")) # 獲取所有的a標籤,並遍歷列印a標籤中的href的值 for item in bs.find_all("a"): print(item.get_text())
#選擇元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.head)
print(soup.p)
#獲取名稱
print(soup.title.name)
print(soup.p.attrs['name'])
print(soup.p['name'])
#獲取內容
print(soup.p.string)
#獲取子孫節點
print(soup.p.children)
for i, child in enumerate(soup.p.children):
print(i, child)
3.find_all( name , attrs , recursive , text , **kwargs )
可根據標籤名、屬性、內容查詢文件,返回所有符合條件的內容
#通過標籤
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))
print(type(soup.find_all('ul')[0]))
#通過屬性
print(soup.find_all(attrs={'id': 'list-1'}))
print(soup.find_all(attrs={'name': 'elements'}))
print(soup.find_all(id='list-1'))
print(soup.find_all(class_='element'))
#通過text
print(soup.find_all(text='Foo'))
4.find( name , attrs , recursive , text , **kwargs )
find返回單個元素,find_all返回所有元素
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find('ul'))
print(type(soup.find('ul')))
print(soup.find('page'))
find_parents() find_parent()
find_parents()返回所有祖先節點,find_parent()返回直接父節點。
find_next_siblings() find_next_sibling()
find_next_siblings()返回後面所有兄弟節點,find_next_sibling()返回後面第一個兄弟節點。
find_previous_siblings() find_previous_sibling()
find_previous_siblings()返回前面所有兄弟節點,find_previous_sibling()返回前面第一個兄弟節點。
find_all_next() find_next()
find_all_next()返回節點後所有符合條件的節點, find_next()返回第一個符合條件的節點
find_all_previous() 和 find_previous()
find_all_previous()返回節點後所有符合條件的節點, find_previous()返回第一個符合條件的節點
5.css選擇
通過select()直接傳入CSS選擇器即可完成選擇
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))
for ul in soup.select('ul'):
print(ul.select('li'))
#獲得屬性
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
#獲取內容
for li in soup.select('li'):
print(li.get_text())
三、BeautifulSoup4四大物件種類
BeautifulSoup4將複雜HTML文件轉換成一個複雜的樹形結構,每個節點都是Python物件,所有物件可以歸納為4種:
1.Tag
我們可以利用 soup 加標籤名輕鬆地獲取這些標籤的內容,這些物件的型別是bs4.element.Tag。但是注意,它查詢的是在所有內容中的第一個符合要求的標籤。
print(type(bs.a))
對於 Tag,它有兩個重要的屬性,是 name 和 attrs:
2.NavigableString
既然我們已經得到了標籤的內容,那麼問題來了,我們要想獲取標籤內部的文字怎麼辦呢?很簡單,用 .string 即可
print(type(bs.title.string))
3.BeautifulSoup
BeautifulSoup物件表示的是一個文件的內容。大部分時候,可以把它當作 Tag 物件,是一個特殊的 Tag,我們可以分別獲取它的型別,名稱,以及屬性
4.Comment
Comment 物件是一個特殊型別的 NavigableString 物件,其輸出的內容不包括註釋符號。
四、遍歷文件樹
1、.contents:獲取Tag的所有子節點,返回一個list
# tag的.content 屬性可以將tag的子節點以列表的方式輸出
print(bs.head.contents)
# 用列表索引來獲取它的某一個元素
print(bs.head.contents[1])
2、.children:獲取Tag的所有子節點,返回一個生成器
for child in bs.body.children:
print(child)
3.descendants:獲取Tag的所有子孫節點
4、.strings:如果Tag包含多個字串,即在子孫節點中有內容,可以用此獲取,而後進行遍歷
5、.stripped_strings:與strings用法一致,只不過可以去除掉那些多餘的空白內容
6、.parent:獲取Tag的父節點
7、.parents:遞迴得到父輩元素的所有節點,返回一個生成器
8、.previous_sibling:獲取當前Tag的上一個節點,屬性通常是字串或空白,真實結果是當前標籤與上一個標籤之間的頓號和換行符
9、.next_sibling:獲取當前Tag的下一個節點,屬性通常是字串或空白,真是結果是當前標籤與下一個標籤之間的頓號與換行符
10、.previous_siblings:獲取當前Tag的上面所有的兄弟節點,返回一個生成器
11、.next_siblings:獲取當前Tag的下面所有的兄弟節點,返回一個生成器
12、.previous_element:獲取解析過程中上一個被解析的物件(字串或tag),可能與previous_sibling相同,但通常是不一樣的
13、.next_element:獲取解析過程中下一個被解析的物件(字串或tag),可能與next_sibling相同,但通常是不一樣的
14、.previous_elements:返回一個生成器,可以向前訪問文件的解析內容
15、.next_elements:返回一個生成器,可以向後訪問文件的解析內容
16、.has_attr:判斷Tag是否包含屬性