首頁 > 軟體

python爬蟲beautiful soup的使用方式

2022-08-19 22:01:49

前言

 簡述bs4:使用pip install beautifulsoup4將bs4包安裝到當前的python直譯器環境,使用from bs4 import BeautifulSoup匯入BeautifulSoup類,進而生成BeautifulSoup類範例並呼叫範例相應的屬性和方法。

bs類似於正則查詢字串,不過不需要我們自己寫正規表示式,bs4已經將處理爬蟲資料時的實際問題進行了統一歸類並提出瞭解決方法,即:將處理html檔案字串時遇到的問題進行簡化並給出api,以便於對html字串檔案進行資訊提取和篩選(不需要自己寫正則了)。

一,Beautiful Soup簡介

 Beatifil soup提供一些簡單的、python式的函數用來處理導航、搜尋、修改分析樹等功能。它是一個工具箱,通過解析檔案為使用者提供需要機取的資料,因為簡單,所以不需要多少程式碼就可以寫出一個完整的應用程式。
Beautiul Soup自動將輸入檔案轉換為Unicode編碼,輸出檔案轉換為utf8編碼。你不需要考慮編碼方式,除非檔案有指定一個編碼方式,這時,Beautiful soup就不能自動識別編碼方了。然後,你僅僅需要說明—下原始編碼方式就可以了。一般的編碼為:utf8,gb2312等。
Beautiful Soup已成為和bxml、html6lib一樣出色的python直譯器,為使用者靈活地提供不同的解析策胳或強勁的速度。

總結:Beautiful Soup依據給定的直譯器來解析html檔案,其依據html中標籤把html檔案在記憶體中轉化為類似於二元樹的資料結構,並通過實現的查詢方法來查詢二元樹以得到我們想要的爬蟲資料。也就是Beautiful Soup專門用於處理html這種有著規範格式的檔案字串,他會自動補全html標籤以及根據標籤層級結構進行檔案格式化,使其更美觀,而且支援query各種標籤。

二,Beautiful Soup的解析器

2.1 各種解析器一覽

2.2 引入解析器的語法

# soup物件 = BeautifulSoup(爬取得到的檔案字串, 解析器)
soup = BeautifulSoup(html, 'lxml')

三,Beautiful Soup解析得到的四種物件

3.1 四種物件 一覽

Beautiful Soup將複雜HTML檔案轉換成一個複雜的樹形結構,每個節點都是Python物件,所有物件可以歸納為4種: Tag , Navigablestring , BeautifulSoup , Comment .

具體指代如下:BeautifulSoup指代整個html檔案,即document。

3.2 bs物件的tag屬性

tag為一個統稱,可以具體為html的各種標籤,如h1-h6,div,a……等。實際上tag與一個節點物件繫結,這個節點物件擁有string,name,parent,attrs等屬性,指代一個html標籤。注:只有第一個先出現的tag會被捕捉到。

詳細如下圖:

舉例如下:

soup = BeautifulSoup(html, 'lxml')
title = soup.title # 獲取檔案的標題,並與變數title繫結
 
# tag物件常見的屬性如下:
title.name # 返回當前tag的標籤名稱,該屬性可讀寫
title.string # 獲取當前tag的navigatiblestring物件
title.parent # 獲取當前tag的父節點
title.attrs # 獲取當前tag的屬性字典
 
 
# tag物件常見的方法如下:
title.get('class') # 括號裡面寫屬性名稱,title.get('屬性名稱')
title.get('href')
title.get_text() # 獲取tag的元素內容,與string一模一樣

3.3 bs物件的prettify屬性及prettify()方法

用於列印整個格式化之後的html檔案,會自動補全缺少的標籤。

from bs4 import BeautifulSoup
soup = BeautifulSoup('<b id="boldest"> ','lxml')
soup.prettify()
soup.prettify
# 上面兩個等價

3.4 bs物件tag物件的屬性獲取

屬性可以通過tag['key']來讀取,也可以用一個全新的變數來繫結tag的attrs屬性進行存取。或者使用tag.get(attr_name)來獲取屬性的value。另外attrs是一個字典,支援字典的增刪改查等操作,從而操作tag的屬性。

多值屬性指的是某些標籤屬性如class,charset……等具有多個屬性值,如:<class="mmd mmd2 mmd3">,對於這種標籤,bs將他們的屬性值放在一個list中。而如id等屬性只有一個值,他們的屬性值為str型別。多值屬性列表會自動轉換為html裡面的多值屬性語法格式。

css_soup = BeautifulSoup('<p class="body"></p>')
css_soup.p['class']
# ["body"]
 
id_soup = BeautifulSoup('<p id="my id"></p>')
id_soup.p['id']
# 'my id'

3.5  NavigableString物件

一般指tag.string,他是一個偽字串物件,使用str()將其轉換為python的字串即可。轉換之後本質上等同於python的字串型別。所有字串的屬性及對字串的方法都對其適用。

也可以不使用str()轉換,直接使用tag.text就是一個字串。

他指代某個標籤裡面的文字內容,而不包括裡面巢狀的標籤。由於其類似字串,所以無法修改,但是可以使用replace_with() 方法將其修改為其他字串。

from bs4 import BeautifulSoup
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>','lxml')
tag = soup.b
print(tag.string)
print(type(tag.string))
# Extremely bold
# <class 'bs4.element.NavigableString'>
 
#---------------------------------------------------#
unicode_string = str(tag.string)
print(unicode_string)
print(type(unicode_string))
# Extremely bold
# <class 'str'>
 
#---------------------------------------------------#
tag.string.replace_with("No longer bold")
print(tag)
# No longer bold

3.6 comment物件及beautiful soup物件

瞭解即可。beautiful soup物件指代document檔案物件,本質上也是一個tag;comment指代html檔案中的註釋內容,是一種特殊的 NavigableString物件,實際中應注意註釋混在元素內容之中,造成資料汙染。

說其是一種特殊的 NavigableString物件,是因為:tag.string可以為一個 NavigableString物件,也有可能為一個comment物件。但是一般使用tag.string來存取元素內容,而不是元素裡面的註釋。

使用tag.prettify屬性來列印出某個tag裡面的所有內容,來判斷使元素內容還是註釋。

四,標籤的定位

使用bs最重要的部分就是標籤定位,定位之後才能獲取得到我們想要的資料。各種定位方法都是基於對html解析樹的操作,類似於二元樹從一個節點向四周尋找節點。所有我們需要做的就是:先定位到一個容易定位的二元樹節點,再從這個節點定位到我們需要的節點。或者使用css選擇器精準定位。

4.1 find()&find_all()方法

官方名字為過濾器,實際上就是通過正則匹配到我們想要的字串。下面只介紹find_all(),find只能找一個,一般不使用。

需要注意find_all()的引數,可以是一個tag_name,一個正則物件,一個列表(如,['div','a']),一個keyword(如,id="mmd"),一個True……

 具體用法如下圖:

tag
soup.find_all('b')
# [<b>The Dormouse's story</b>]
 
正則
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b
 
列表
soup.find_all(["a", "b"])
# [<b>The Dormouse's story</b>,
#  <a class="sister" href="http://example.com/elsie" rel="external nofollow"  id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" rel="external nofollow"  id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" rel="external nofollow"  id="link3">Tillie</a>]
 
True
for tag in soup.find_all(True):
    print(tag.name)
# html
# head
# title
# body
 
方法
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)
# [<p class="title"><b>The Dormouse's story</b></p>,
#  <p class="story">Once upon a time there were...</p>,
#  <p class="story">...</p>]

常用寫法:

4.2 select()方法

引數是一個css選擇器。 與前端css中的各種選擇器一模一樣,這個比find_all()更加常用,畢竟與前端比較類似,容錯率高。

soup.select("title")
# [<title>The Dormouse's story</title>]
 
soup.select("p:nth-of-type(3)")
# [<p class="story">...</p>]

4.4 節點之間的各種關係定位函數

參看官方檔案,bs4官方檔案

上面的selec和find_all()基本上能夠定位到任何位置了,不需要找爸爸找兒子這種形式去定位了。

到此這篇關於python爬蟲beautiful soup的使用方式的文章就介紹到這了,更多相關python beautiful soup 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com