Coding起來-Python自動化爬蟲-BeautifulSoup美麗湯套件-方法教學
哈囉,由於小弟非常喜歡亂逛線上電商平台,但又有點懶,每次都要手動自己滑觀看商品,所以今天來向大家介紹一個爬取網頁非常重要的套件-BeautifulSoup,有了它我們可以快速的爬取網頁上任何我們所需的資料,這樣一鍵就能搞定,省掉了很多時間,嘿嘿,很棒
1. Beautiful Soup 套件是什麼?
資料科學領域,在蒐集資料的過程中,我們常使用三種方式來得到資料,線下的方式直接蒐集(填問卷、購買紀錄、訪談等),線上網站所提供的API,或是自己撰寫爬蟲程式從網頁html中萃取我們所需的資訊,我們先將網頁html載下來,並用BeautifulSoup套件進行萃取,這個套件幫助開發者快速的達到爬取網頁資料目的,非常好用
2. BeautifulSoup套件安裝
BeautifulSoup: 能夠使用其豐富的內鍵方法來解析載下來的html結構,幫助我們快速爬取所需資料
pip install beautifulsoup4
Request: 剛剛一直提到要先載入html結構,才能進行BeautifulSoup的進一步爬取,那這個套件就是幫助我們載入我們指定的網頁html結構
pip install requests
3. 載入頁面並透過BeautifulSoup解析
我這邊採用自己的Medium頁面來為大家講解各種實作方法喔
Step 1: 使用request套件的get()方法,將網頁,來載入指定網頁的html結構
import requests request_html = requests.get("https://medium.com/@chwang12341")
Step 2: 採用Beautiful套件裡解析html的方法來將傳回來的html結構字串,轉化為可以解析的結構與型態
a. prettify()幫我們輸出成排好版的HTML架構內容
from bs4 import BeautifulSoup soup = BeautifulSoup(request_html.text, “html.parser”) ## 印出排好版的HTML架構 print(soup.prettify())
4.補充: 編碼問題
a. 情況: 如果執行上面的指令後,發現解碼出來的內容中文的地方出現亂碼,才需要進行這個步驟
b. 原則上BeautifulSoup解析html會是以”utf-8"格式進行編碼,如果出現亂碼就是說我們需要改變編碼格式
小叮嚀: 我這邊使用的網頁在utf-8下進行編碼,是不會出現亂碼的,所以如果改成”gb18030"就會出現亂碼,所以要先確定自己解析出來的內容喔
c. 測試:
使用utf-8進行編碼
import requestsfrom bs4 import BeautifulSoup request_html = requests.get("https://medium.com/@chwang12341") print(request_html.encoding) ## 印出編碼方式 soup = BeautifulSoup(request_html.text, "html.parser")print(soup.encoding)## 印出編碼方式 ## 印出排好版的HTML架構 print(soup.prettify())
結果: 擷取片段
使用gb18030進行編碼
import requestsfrom bs4 import BeautifulSoup request_html = requests.get(“https://medium.com/@chwang12341") ## 更改編碼方式 request_html.encoding = ‘gb18030’ print(request_html.encoding)## 印出編碼方式 soup = BeautifulSoup(request_html.text, “html.parser”) print(soup.encoding)## 印出編碼方式 ## 印出排好版的HTML架構 print(soup.prettify())
結果: 擷取片段
d. 結論: 從兩個取片段的結果顯示,用了gb18030進行編碼會出現亂碼,而utf-8不會出現亂碼,大家遇到解碼問題的時候不彷試試不同解碼方式喔
5. 利用HTML標籤或屬性來找尋我們需要的資料
a. (解析好的變數).(tag) : 直接以標籤(tag)搜尋
i. 它會將整個標籤印出來(ex. print(soup.title)、print(soup.h1)),如果想獲得裡面的文字內容就好,使用.text或.string,都能幫我們轉換成字串
ii. 舉例:
## 查看我們title這個標題tag底下的文字內容 print(soup.h1) ## Chwang print(soup.title) ## Chwang — Medium print(soup.title.text) ## Chwang — Medium print(soup.title.string) ## Chwang — Medium
b. find(): 跟上面一樣,也是用標籤來搜尋節點,將欲找尋的標籤(tag)放入,就能查詢
## 查看我們title這個標題tag底下的文字內容 print(soup.find(“title”)) print(soup.find(“h1”)) print(soup.find(“title”).text )print(soup.find(“title”).string)
c. find_all(): 跟前面的一樣根據標籤來查找,但會返回多個擁有一樣條件的節點,返回的型態是串列(list)
i. 搜尋所有h1標籤的節點
## 印出所有是h1標籤的內容 find_all = soup.find_all(“h1”) print(find_all)
ii. 設定limit參數,這樣就可以自行決定要返回幾個符合條件的節點
## 印出四個是h1標籤的內容 find_all = soup.find_all(“h1”, limit = 4 ) print(find_all)
iii. 因為符合標籤的節點可能很多,所以可以給定一些指定標籤(tag)裡的條件,這樣就會抓出我們想要的節點
## 印出符合 h1 與 h1裡面的id=”a65f” 條件的節點,但因為id值是唯一的,所以限制數量沒有意義## 印出2個是h1標籤的內容 find_all = soup.find_all(“h1”, id=”a65f”, limit = 2) print(find_all)
vi. 同時抓區多個標籤
## 印出所有是h1和title標籤的內容 find_all = soup.find_all([“title”,”h1"], limit = 4) print(find_all)
d. select_one() : 在某一個節點(標籤tag)下,只有一個節點的話,可以用這種方法來搜尋
i. 舉例: 找到div tag 底下一個包含a tag的 節點
H1_TAG = soup.find(“div”) print(H1_TAG.select_one(“a”))
e. select(): 在某一個節點(標籤tag)下,搜尋所有包含指定標籤(tag)的節點
i. 舉例: 找到div tag 底下所有包含 a tag 的節點
## 印出div標籤底下,所有a標籤的節點 H1_TAG = soup.find(“div”) print(H1_TAG.select(“a”))
6. 以Class屬性來搜尋節點
筆記: 使用class_= “(class值)” 來查詢符合的節點
a. find()
## 印出是h1標籤,且class = “cr q cs bt ct bu cu cv cw z”的一個節點 find = soup.find(“h1”,class_=”cr q cs bt ct bu cu cv cw z”) find
b. find_all()
## 印出是h1標籤,且class = fu fv bu bt ct fw fx fy cr”的所有節點find_all = soup.find_all(“h1”,class_=”fu fv bu bt ct fw fx fy cr”) find_all
c. select()
i. 寫法比較特別是用.來搜尋class名稱
ii.舉例
## 印出div標籤底下,所有標籤的節點中符合class=”gb ha”的節點 DIV_TAG = soup.find(“div”) print(DIV_TAG .select(“.gb”, limit=1))
7. 向上搜尋父節點
筆記: 前面提到的都上向下去搜尋子節點,這邊介紹如何向上搜尋父節點,利用find_parent()或find_parents()來達成效果
舉例:
# <a class=”bn bo az ba bb bc bd be bf bg dz bj br bs” find = soup.find(“a”,class_=”bn”) print(find.find_parents(“div”, limit=1))
8.向前、後搜尋節點
筆記: 利用find_previous_sibilings() 與 find_next_sibilings() 來達到搜尋同層級下,前、後的節點
a. find_previous_siblings(): 搜尋前一個節點
## 下一個節點 next_node = soup.find(“div”, class_=”et”) ## 上一個節點 previous_node = next_node.find_previous_siblings(“div”) print(previous_node)
<a bo az ba bb bc bd be bf bg dz bj br bs”
b. find_next_siblings(): 收尋下一個節點
## 上一個節點 previous_node = soup.find(“div”, class_=”r”) ## 下一個節點 next_node = previous_node.find_next_siblings(“div”) print(next_node)
9. 獲取屬性值
筆記: 利用get(),來獲取標籤內的屬性值
舉例: 從符合條件的節點中,萃取出href的值
##找到所有符合條件的節點 results = soup.find_all(“a”,class_=”bn”) for tag in results: ## 印出屬性href的值 print(tag.get(“href”))
10. 取得連結的文字
<a bo az ba bb bc bd be bf bg dz bj br bs”
筆記: 利用getText(),來取得連結文字
##找到所有符合條件的節點 results = soup.find_all(“a”,class_=”bn”) for tag in results: ## 印出連結文字 print(tag.getText())
小提醒: 由於我的網頁會不斷更新內容, 所以大家使用上面的範例程式,可能會有不同結果喔!!
重要: 因為網站會隨時間變化,可能會有更新,我這篇是以前寫的 ,所以code可能就不能直接拿來使用,但是觀念是一樣的喔!! 大家可以拿手邊的網站試試!!
這次主要介紹BeautifulSoup有哪些用法,有了BeautifulSoup後大家就可以網頁資料爬起來了,希望這次對大家有幫助喔!!
Reference:
https://www.itread01.com/content/1546441864.html
[Python爬蟲教學]7個Python使用BeautifulSoup開發網頁爬蟲的實用技巧
Photo by Stanley Dai on Unsplash 而在開發的過程中,常會需要搜尋HTML的節點,本文將分享幾個常用的方法,包含: pip install beautifulsoup4 pip install…www.learncodewithmike.com