iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
自我挑戰組

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

[Day 5] 餐前濃湯 pt.2-BeautifulSoup meets Stocks

上一篇我們設定完了vagrant,安裝完了BeautifulSoup
這一篇我們就要來讓BeutifulSoup正式發功啦
廢話不多說,砸們累狗~

BeautifulSoup的第一大魔王:

好的,根據我們專業股市分析團隊a.k.a財報狗的書籍指出
要知道哪支股票有潛力,首先就要了解公司財報
因此我們就先來把公司財報的資料撈出來吧
首先先進我們的公開資訊觀測站的財報網頁,這裡我們採IFRSs後
傳送們在這https://mops.twse.com.tw/mops/web/t163sb01
然後一進去之後我們就會發現
就會發現...

啊我的財報資料勒,啊挖A財報資料勒
沒錯,這裡網頁使用了一個相當特殊的方式呈現資料
怎麼個特殊法呢,這裡我們先使用一個魔法
首先先看到你的鍵盤,看到了齁
按下那顆可愛的F12
或是你也可以抬起頭來,再網頁空白處點選右鍵,選擇檢查

好的你的網頁下面左邊右邊或上面,反正其中一面應該會出現像是console的東東
這個東西就叫做開發人員工具,專門用來監控修改網頁資料用的
不過別擔心,這些修改都只會呈現在你的本地端而已
啊如果你真的把人家的網頁改成功了,相信我,該愧疚的不是你,是那些寫網頁的
回到正題,我們把這邊的選項選成network

之後我們在公司代號或簡稱欄位隨便輸入,這裡就輸入1201,然後查詢

可以發現我們的console多了好幾個東東,其中一個叫做ajax_t163sb01
這就代表網頁呈現方式是用ajax方式動態呈現的
你直接撈只會撈到靜態框架這些空氣而已

那怎麼辦呢?簡單~
ajax這東西說穿了其實也只是用POST方式送出request把資料撈回來做動態更新元件而已
因此我們只要在送request之前多一個header,然後把我們要送出去的data用dict包起來一起送出去就好
程式碼如下

import requests
import json
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)
file = open('res.html', 'w', encoding="utf-8")
file.write(res.text)
file.close()

第一二行不用說,就是把套件import進來
由於json套件python已經幫你內建好了就不用下載了
第三行是你要送的url目的地
第四到第十六行就是你要送的data內容
比較需要提的地方有兩個
第一個是co_id 代表公司代號
第二個是isnew,這代表是否直接撈最新財報資料
是的話就設定true(記得是要用字串傳,不是bool),就會撈回醉金財報
否的話就設定false,然後財報的年度跟季度都要填,分別填在year跟season欄位
第十七到十九行是設定header,就是跟server講說你何許人也
雖然這裡server好像也不會檢查就是
最後就是送出request,並且把結果用res接住啦
這裡的最後我們用點比較不一樣的方式輸出結果
我們開啟一個file物件,然後把這物件設定成寫入模式,檔名叫做res.html,後面記得編碼模式選utf-8以免報錯
然後我們把我們的res的原始碼存到file內就好啦
記得最後要把file這個class關掉釋放記憶體

好的我們就可以來執行看看結果如何啦

一樣剛剛講過了,python是個沉默寡言的人,只要你不print不搞事,他是不會有任何反應的
不過大家可以看到在我們的py檔旁邊多了一個我們剛剛定義的res.html檔

點進去看如果是長這樣,那就表示撈取成功啦~

幫我把牛魔刀拿來: 開始支解HTML原始碼

前面提到BeautifulSoup最重要的目的就是把HTML原始碼做分割,取出我們要的部分
所以這個環節我們就要來實際開切HTML啦
HTML:

師承前面的code,我們先把file output的部分,也就是最後三行給刪除
除此之外,我們會需要原始頁面來幫助我們尋找我們要的部分
所以一樣,我們先在財報頁面輸入1201,然後按下查詢
此時你的頁面應該長這樣

接著我們就要來找哪些部份是我們要的資訊啦
這次我們先把流動資產這一欄資料給撈出來吧,那怎麼撈呢?

我們對流動資產這四的字的區域按下右鍵>檢查

就可以看到這個資料是在原始碼的哪個區域
所以我們可以看到這筆資料是由一個tr的html tag包起來的
因此我們就先把所有有tr tag的資料拿出來
首先記得在檔案開頭引用我們的bs4的BeautifulSoup套件
from bs4 import BeautifulSoup
撈取方式使用下列code

soup = BeautifulSoup(res.text, 'html.parser')
tr_tag = soup.find_all('tr')

第一行就是把我們的原始碼使用html.parser的方式支解
第二行則是支解完之後我們把所有tr標籤的東東全部找出來
這些步驟操作完後,你的code應該會長這樣

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')

此時我們可以先來print一下看看長怎樣 先在最後面加入
print(tr_tag)

可以看到好像有撈東西出來的,但這撈出來的東西實在是有點讓人密集恐懼症發作
畢竟這個網頁的tr tag也不只一個,所以他會把所有符合tr tag的資料都拿出來
進而造成這種密恐發作輸出
不過還好,這個搜尋結果是用list的方式取得的
因此我們可以用遍歷的方式將list內元素一個一個print出來
我們把print改成下列程式碼

for i in tr_tag:
	print(i)

最後再看一下執行結果

這樣就舒服多了
可是tr結果這麼多,怎麼找到我們要的流動資產資料呢
我們再回到我們的原始碼看看,發現我們的目標tr tag有個屬性叫class="even"
所以我們可以再把搜尋條件加上class要是even才拿出來
增加條件的方式我們會使用python的dict,如下面的code所示
tr_tag = soup.find_all("tr", {"class": "even"})
這樣我們就只會撈出是tr tag且class為even的東東了
我們一樣把tr_tag改掉後再執行一次

這次的結果就少了許多了
可以發現我們要的流動資產資料在這個搜尋結果的第四個
所以我們就把第3個index的資料撈出(請不要問我要撈第四個index卻是3,因為人家計算機是re:0粉)
把print這段改成:
print(tr_tag[3])
輸出結果

恭喜你,你成功的用這碗漂亮的湯撈出你人生第一筆資料啦~
不過每次要撈資料都要這樣慢慢比對
不僅對不起你浪費的時間,更對不起這個功能強大的BeautifulSoup還有Python
因此下一篇,我們會教你如何把裡面的東西一次撈出來,並且怎麼轉成JSON方便送給其他人
欲知這個BeautifulSoup還有甚麼隱藏在深處的強大力量
咱們下回分解~


上一篇
[Day 4]餐前濃湯-Vagrant環境設定及BeautifulSoup安裝
下一篇
[Day 6] 餐前濃湯 pt.3-BeautifulSoup,第二型態
系列文
BeautifulSoup網頁爬蟲佐Django伺服器框架附AWS雲端運算服務30

尚未有邦友留言

立即登入留言