iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
1
自我挑戰組

LINE BOT 新手村30日攻略系列 第 19

Day19 Python 爬蟲 Beautiful Soup

  • 分享至 

  • xImage
  •  

LINE BOT 與網路爬蟲結合可以產出更多有趣的玩法
今天開始要跟大家介紹 Python 爬蟲,而今天要介紹的是 Beautiful Soup

那麼什麼是爬蟲呢?
爬蟲是一種可以替我們自動化在網路上蒐集資料的強力工具
這樣一來我們就不必每次都自己到網站上獲取資訊
透過統一的格式內容,加上定期的蒐集資訊,以自訂的格式顯示出來,這樣一來在獲取資訊就會輕鬆很多

安裝 Beautiful Soup

使用 pip 下載

# Python 2
pip install beautifulsoup4

# Python 3
pip3 install beautifulsoup4

基本功能

Beautiful Soup 會透過解析 HTML 原始碼,將其轉換成 Beautiful Soup 物件,利用這個物件就可以輕鬆找到網頁中的內容

我們可以先以 Google 為範例嘗試

from bs4 import BeautifulSoup
import requests

r = requests.get('https://www.google.com/')

if(r.status_code == requests.codes.ok):
    soup = BeautifulSoup(r.text, 'html.parser')

print(soup.prettify())

在第9行的部分,會輸出排版後的 HTML 資料,執行後大致會是這樣

取得節點內容

如果有學過 HTML 的話應該會知道, HTML 是由很多的 tag 組合成的
如果我們要獲取特定 tag 的資料的話,我們可以用 BeautifulSoup 輕鬆達成

例如輸出 title 的內容

print(soup.title)

<title>Google</title>

如果我們只要其中的文字部分,可以使用 .string

print(soup.title.string)

Google

搜尋節點

剛剛的作法只能輸出第一個找到的內容
我們可以使用 find_all 來找到全部特定的 HTML tag ,再透過迴圈一一輸出

a_tags = soup.find_all('a')
for tag in a_tags:=
  print(tag.string)

取得節點屬性

如果要取得 HTML 節點的屬性,可以使用 get

for tag in a_tags:
    print(tag.get('href'))

同時搜尋多種標籤

如果要同時搜尋多種 HTML tag ,可以用 list 傳入 find_all 來獲取

a_tags = soup.find_all(['a','b'])
for tag in a_tags:
    print(tag)

限制搜尋節點數量

find_all 可以加上搜尋數量的限制

a_tags = soup.find_all(['a','b'], limit=2)
for tag in a_tags:
    print(tag)

限制遞迴搜尋

預設情況下使用 find_all 會搜尋全部的節點,可以透過參數限制只搜尋第一層的內容

a_tags = soup.find_all(['a','b'], recursive=Falses)
for tag in a_tags:
    print(tag)

以 HTML 屬性搜尋

我們除了根據 tag 外,也可以用 HTML 的屬性搜尋

a_tags = soup.find(id="footer")
print(a_tags)

另外,我們也可以結合 tag 與屬性進行搜尋

a_tags = soup.find_all('span', id="footer")
print(a_tags)

以 CSS 搜尋

a_tags = soup.find_all('b', class_="gb1")
print(a_tags)

以文字內容搜尋

如果要搜尋特定的文字,可以結合 find_allstring 一起使用

a_tags = soup.find_all('title', string="Google")
print(a_tags)

實作

例如我想要爬學校網站的公告

觀察一下網頁後,會發現到公告的標題都會被放在 class 是 ptname 的 span 當中

所以我們可以先把 class='ptname' 的 span 都拿出來看看

我們要的只有標題的文字,都存放在 a 的 tag 當中

from bs4 import BeautifulSoup
import requests

r = requests.get('http://www.tnfsh.tn.edu.tw/files/501-1000-1012-1.php?Lang=zh-tw')

if(r.status_code == requests.codes.ok):
    soup = BeautifulSoup(r.text.encode('iso-8859-1').decode('utf-8'), 'html.parser')
a_tags = soup.find_all('span', class_="ptname")
#print(r.encoding)
for a_tag in a_tags:
    print(a_tag.a.string)

這樣一來就完成囉!

因為我們爬的網站是中文,所以要特別注意要使用 utf-8
在網路上看到的解法是先 encode 再 decode ,這邊實作出來也是沒問題的

參考資料

GTW Python 使用 Beautiful Soup 抓取與解析網頁資料,開發網路爬蟲教學
知乎 Python3 中文亂碼如何求解


上一篇
Day18 口罩查詢系統 - 3
下一篇
Day20 Python 爬蟲 Selenium
系列文
LINE BOT 新手村30日攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言