免責聲明:我們盡力確保本文的正確性,但本文不代表任何投資的建議,我們也無法擔保因使用本文的內容所造成的任何損失。如對本文內容有疑問,請詢問財經相關的專家。
除了手動瀏覽網站並抓取交易數據外,使用爬蟲 (crawlers) 可以達到同樣的效果,而且省下機械化的手動操作。本文的目標是學習如何透過爬蟲自動化獲得交易數據的過程。如果只要單次抓取少量資料,爬蟲不是很必要,但長期來說會節省時間。
本節透過一個實例來說明如何撰寫 Selenium 程式。Selenium 有數種 language binding,我們這裡以 Python 為例。由於網頁過一陣子可能會改版,不要硬背教程所提供的爬蟲的程式碼,而要透過閱讀程式碼學習如何自行手動撰寫。
我們這個爬蟲的動作拆解如下:
- 前往 Yahoo Finance 網頁
- 在搜尋框輸入我們感興趣的投資標的,像是
SPY
(標普指數) - 按下輸入鈕,刷到 SPY 所在的頁面
- 切換到 Historical Data 所在的分頁
- 開啟 Time Period 的設定框
- 將時距調到 5 年 (
5Y
) - 按下 Done 按鈕關閉該設定框
- 按下 Apply 按鈕確認該設定生效
- 按下 Download Data 連結下載 CSV 檔案
讀者可先手動操作一下,感受這個過程。Selenium 程式就是把這個過程轉成程式碼,寫起來沒有什麼複雜的邏輯。由於整個範例程式碼偏長,我們將完整的程式碼放在這裡。在本文中,我們將這個爬蟲拆解,讓讀者感受一步步完成爬蟲的感覺。
一開始要先引入相關的模組:
from selenium import webdriver
在此處,我們將搜尋目標設為 "SPY"
:
# We want to get the data of SPDR S&P 500 ETF (SPY)
targetAsset = "SPY"
在本範例,我們使用 Chrome 瀏覽器:
# Create a new instance of the Chrome driver
driver = webdriver.Chrome()
撰寫 Selenium 程式時不一定要使用 Chrome,目前幾個主流的瀏覽器都有相對應的 web driver 可下載。
一開始先前往 Yahoo Finance 的頁面:
# go to the Yahoo Finance page
driver.get("https://finance.yahoo.com/")
我們將錨點定到搜尋框,輸入搜尋目標,並執行搜尋的動作:
# find the input box
inputElement = driver.find_element_by_css_selector("#fin-srch-assist input")
# type in the search
inputElement.send_keys(targetAsset)
# submit the form (although google automatically searches now without submitting)
inputElement.submit()
定錨的方式有很多,像是 HTML tag、class、id 等,基本上,CSS selector 可用的方式都可以用來定錨。Selenium 提供數個函式呼叫,以對應不同的錨點,在這些函式中,以 CSS selector 為錨點的函式算是通用性最好的,筆者大部分都會用這類函式來操作瀏覽器。
由於我們要等頁面刷新,故讓程式休息 10 秒:
# Wait the page to refresh.
time.sleep(10)
有時候要讓程式暫停數秒,等網頁刷完,跑出新的 elements,爬蟲才可進行下一步動作。以 Python 來說,可搭配 time
模組來暫停程式。
切換到 Historical Data 所在的分頁:
items = driver.find_elements_by_css_selector("a span")
for item in items:
if item.text == "Historical Data":
item.click()
break
要注意到這個函式回傳的東西是串列,要透過迴圈取出其內的 web element。檢查 element 的文字來確認 element 是一個相對簡單且常用的方式。
接下來打開選擇時距的選單,選擇 5 年後按確認:
arrows = driver.find_elements_by_css_selector(".historical div div span svg")
arrows[0].click()
durations = driver.find_elements_by_css_selector("[data-test=\"date-picker-menu\"] div span")
for duration in durations:
if duration.text == "5Y":
duration.click()
break
buttons = driver.find_elements_by_css_selector("[data-test=\"date-picker-menu\"] div button")
for button in buttons:
if button.text == "Done":
button.click()
break
這裡其實包含三個步驟,開啟選單、選擇時距、按 Done 按鈕以結束選取的動作。我們不會硬要選定單一 element,而是會先選一個小範圍的 elements,再進行第二次篩選,這樣寫起來比較簡單。
按下 Apply 按鈕確認我們的選擇:
buttons = driver.find_elements_by_css_selector("button span")
for button in buttons:
if button.text == "Apply":
button.click()
break
選擇 Download Data 的連結以下載 CSV 表格:
links = driver.find_elements_by_css_selector("a span")
for link in links:
if link.text == "Download Data":
link.click()
break
最後別忘了關掉瀏覽器:
driver.quit()
讀者可參考本文,自行寫出爬取 Yahoo Finance 抓資料的爬蟲。