iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

BeautifulSoup網頁爬蟲佐Django伺服器框架附AWS雲端運算服務系列 第 6

[Day 6] 餐前濃湯 pt.3-BeautifulSoup,第二型態

上一篇我們約略介紹了BeautifulSoup的功用及使用方式
這次我們要來繼續介紹BeautifulSoup如何做到更強大,更符合人性的切割方式了
這篇內容會比較短,因為明天開始就是中秋連假,我要先回老家過節啦~
當然回家期間鐵人賽也是不會斷更的
畢竟斷更就煉不成鐵人了嘛(?
廢話不多說,砸們累狗~

撈取共同資料 = 邏輯問題

相信大家應該應該有玩過邏輯問題
甚麼叫邏輯問題呢,簡單來說就是
1, 3, 5, 7, 9, 11, ? 請問 ? 內的數字是啥
沒錯,就是86413,因為這個數列是所有正整數代入下面多項式的結果
f(x) = 120(x-1)(x-2)(x-3)(x-4)(x-5)(x-6) + (2x-1)

好啦,其實這個就是一個標準的等差數列,大家都知道下一個最有機率出現的數字就是13
因為我們從觀察可以發現兩數之間相差二,就算可能有意外,但還是這個可能最高
用BeautifulSoup切資料時也一樣,我們也可以從tr, td的屬性去猜測我們要的資料共同特徵是甚麼
我們可以再回到網頁的原始碼看看

從原始碼可以發現,我們需要的所有資料都包在tr標籤內
而且class的名稱要馬是odd要馬是even
那這樣我們的目標就非常明確了
我們只要叫服務生出來然後說
「請幫我把tr的部分切出來就好了,啊對我只要odd跟even剩下的部分我不要謝謝」
(請不要真的在餐廳嘗試,被主廚趕出來本練功坊概不負責)

那怎麼用程式做這件事情呢
切出tr的部分昨天已經完成了,找單一class名稱也完成了
那要怎麼做到尋找任一指定元素呢?簡單~
只要把我們的搜尋條件變成list,然後做成dict的value就好了,如下面的code所示

tr_tag = soup.find_all("tr", {"class": ["odd", "even"]})

那我們一樣把搜尋條件修改成這個形式,然後把list的元素用迭代(Iterative, 就是用for迴圈啦)print出來
所以現在的程式碼應該會變成如下所示:

import requests
import json
from bs4 import BeautifulSoup
url = 'https://mops.twse.com.tw/mops/web/ajax_t163sb01'
data={
        'co_id': '1201',
        'queryName': 'co_id',
        'inputType': 'co_id',
        'isnew': 'true',
        'TYPEK': 'all',
        'encodeURIComponent': '1',
        'step': '1',
        'firstin': '1',
        'off': '1',
        'year': None,
        'season': None
}
headers = {
    #'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
}
res = requests.post(url=url,data=data,headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
tr_tag = soup.find_all("tr", {"class": ["odd", "even"]})
for i in tr_tag:
    print(i)

最後執行結果如下(用筆電背景不一樣純屬自然現象,敬請安心食用)

我們發現似乎還是有一些雜物在我們的結果裡面
像是有些空的tr內容,還有一些不必要的備註
一樣,我們再做一次觀察
發現我們需要的資料就是包含要馬三個或五個的td標籤
所以我們就再把只含三個獲五個td標籤的tr標籤撈出來
因此我們再修改一下我們的程式碼

首先,我們先定義一個空的list,等等準備把撈出來的tr標籤放進來
tr_result = []
然後我們修改一下我們的迭代內容,改成如下:

for i in tr_tag:
    td_tag = i.find_all("td")
    if len(td_tag) == 3 or len(td_tag) == 5:
        print(td_tag)
        tr_result.append(i)

這段的目的是我們把每個tr標籤內的td標籤撈出來,並且看看td標籤是否為三個或五個
是的話我們把它顯示出來(這裡是為了方便觀察,正式版本可以把這個Code刪掉)
並且存在我們剛剛定義的list內
最後我們再執行一次看看結果,這次的資料就變得非常乾淨了

好的到這邊,我們已經成功地把所有需要的資料都撈下來了
接下來就會教大家如何再進一步去蕪存菁,只把我們要的數據留下來
以及這些數據要如何儲存
欲想知道這個複雜的程式碼如何到最後變成漂亮舒服的數據
咱們下回分解~


上一篇
[Day 5] 餐前濃湯 pt.2-BeautifulSoup meets Stocks
下一篇
[Day 7] 餐前濃湯 pt.4-資料內文取得及儲存
系列文
BeautifulSoup網頁爬蟲佐Django伺服器框架附AWS雲端運算服務30

尚未有邦友留言

立即登入留言