1. 程式人生 > 實用技巧 >python常用第三方庫---BeautifulSoup庫(搬運)

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是否包含屬性