來源:Python/ target=_blank class=infotextkey>Python數據之道
作者:Peter
整理:陽哥
大家好,我是陽哥。
今天來跟大家分享用 BeautifulSoup 獲取信息的一些知識點,文章內容由公眾號讀者 Peter 創作。
歡迎各位童鞋向公眾號投稿,點擊下面圖片了解詳情!
爬蟲,是學習Python的一個有用的分支,互聯網時代,信息浩瀚如海,如果能夠便捷的獲取有用的信息,我們便有可能領先一步,而爬蟲正是這樣的一個工具。
Beautiful Soup 是一個可以從html或XML文件中提取數據的Python庫。由于 BeautifulSoup 是基于 Python,所以相對來說速度會比另一個 Xpath 會慢點,但是其功能也是非常的強大,本文會介紹該庫的基本使用方法,幫助讀者快速入門。
網上有很多的學習資料,但是超詳細學習內容還是非官網莫屬,資料傳送門:
英文官網:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
中文官網:
https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
本文的主要內容如下:
安裝和使用
安裝
安裝過程非常簡單,直接使用pip即可:
pip install beautifulsoup4
上面安裝庫最后的4是不能省略的,因為還有另一個庫叫作 beautifulsoup,但是這個庫已經停止開發了。
因為BS4在解析數據的時候是需要依賴一定的解析器,所以還需要安裝解析器,我們安裝強大的lxml:
pip install lxml
在python交互式環境中導入庫,沒有報錯的話,表示安裝成功。
使用
使用過程直接導入庫:
from bs4 import BeautifulSoup
解析原理
解析原理
- 實例化一個BeautifulSoup對象,并且將本地或者頁面源碼數據加載到該對象中
- 通過調用該對象中相關的屬性或者方法進行標簽定位和數據提取
如何實例化BeautifulSoup對象
- 將本地的HTML文檔中的數據加載到BS對象中
- 將網頁上獲取的頁面源碼數據加載到BS對象中
案例解析
原數據
假設我們現在本地有一個HTML文件待解析,具體內容如下,數據中有各種HTML標簽:html、head、body、div、p、a、ul、li等
加載數據
from bs4 import BeautifulSoup
fp = open('./test.html','r',encoding='utf-8') # 打開本地文件
soup = BeautifulSoup(fp,'lxml')
soup
所有的數據解析都是基于soup對象的,下面開始介紹各種解析數據方法:
soup.tagName
soup.TagName返回的是該標簽第一次出現的內容,以a標簽為例:
數據中多次出現a標簽,但是只會返回第一次出現的內容
我們再看下div標簽:
出現了2次,但是只會返回第一次的內容:
soup.find('tagName')
find()主要是有兩個方法:
- 返回某個標簽第一次出現的內容,等同于上面的soup.tagName
- 屬性定位:用于查找某個有特定性質的標簽
1、返回標簽第一次出現的內容:
比如返回a標簽第一次出現的內容:
再比如返回div標簽第一次出現的內容:
2、屬性定位
比如我們想查找a標簽中id為“谷歌”的數據信息:
在BS4中規定,如果遇到要查詢class情況,需要使用class_來代替:
但是如果我們使用attrs參數,則是不需要使用下劃線的:
soup.find_all()
該方法返回的是指定標簽下面的所有內容,而且是列表的形式;傳入的方式是多種多樣的。
1、傳入單個指定的標簽
image-20210523170401516
上面返回的是列表形式,我們可以獲取我們想要的內容:
2、傳入多個標簽(列表形式)
需要主要返回內容的表達形式,每個標簽的內容是單獨顯示的
3、傳入正則表達式
比如查看以a開頭標簽的全部內容
查看以li標簽開頭的全部內容:
選擇器soup.select()
主要是有3種選擇器,返回的內容都是列表形式
- 類選擇器:點
- id選擇器:#
- 標簽選擇器:直接指定標簽名
1、類選擇器
2、id選擇器
3、標簽選擇器
直接指定li標簽
4、選擇器和find_all()可以達到相同的效果:
soup.tagName和soup.find('tagName')的效果也是相同的:
層級選擇器使用
在soup.select()方法中是可以使用層級選擇器的,選擇器可以是類、id、標簽等,使用規則:
- 單層:>
- 多層:空格
1、單層使用
2、多層使用
獲取標簽文本內容
獲取某個標簽中對應文本內容主要是兩個屬性+一個方法:
- text
- string
- get_text()
1、text
2、string
3、get_text()
3者之間的區別
# text和get_text():獲取標簽下面的全部文本內容
# string:只能獲取到標簽下的直系文本內容
獲取標簽屬性值
1、通過選擇器來獲取
2、通過find_all方法來獲取
BeautifulSoup實戰
下面介紹的是通過BeautifulSoup解析方法來獲取某個小說網站上古龍小說名稱和對應的URL地址。
網站數據
我們需要爬取的數據全部在這個網址下:
https://www.kanunu8.com/zj/10867.html,右鍵“檢查”,查看對應的源碼,可以看到對應小說名和URL地址在源碼中位置
每行3篇小說在一個tr標簽下面,對應的屬性href和文本內容就是我們想提取的內容。
獲取網頁源碼
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
url = 'https://www.kanunu8.com/zj/10867.html'
headers = {'user-agent': '個人請求頭'}
response = requests.get(url = url,headers = headers)
result = response.content.decode('gbk') # 該網頁需要通過gbk編碼來解析數據
# result
實例化BeautifulSoup對象
soup1 = BeautifulSoup(result,'lxml')
# print(soup1.prettify()) 美化輸出源碼內容
獲取名稱和URL地址
1、先獲取整體內容
兩個信息全部指定a標簽中,我們只需要獲取到a標簽,通過兩個屬性href和target即可鎖定:
# 兩個屬性href和target,不同的方法來鎖定
information_list = soup1.find_all('a',href=re.compile('^/book'),target='_blank')
information_list
2、再單獨獲取兩個信息
通過屬性來獲取URL地址,通過文本來獲取名稱
url_list = []
name_list = []
for i in information_list:
url_list.Append(i['href']) # 獲取屬性
name_list.append(i.text) # 獲取文本
3、生成數據幀
gulong = pd.DataFrame({
"name":name_list,
"url":url_list}
)
gulong
我們發現每部小說的具體地址其實是有一個公共前綴的:
https://www.kanunu8.com/book,現在給加上:
gulong['url'] = 'https://www.kanunu8.com/book' + gulong['url'] # 加上公共前綴
gulong.head()
另外,我們想把書名的《》給去掉,使用replace替代函數:
gulong["name"] = gulong["name"].apply(lambda x:x.replace("《","")) # 左邊
gulong["name"] = gulong["name"].apply(lambda x:x.replace("》","")) # 右邊
# 保存
gulong.to_csv("gulong.csv",index=False) # 保存到本地的csv文件
最后顯示的前5行數據:
總結
本文從BeautifulSoup4庫的安裝、原理以及案例解析,到最后結合一個實際的爬蟲實現介紹了一個數據解析庫的使用,文中介紹的內容只是該庫的部分內容,方便使用者快速入門,希望對讀者有所幫助。