Python Seleium 做動態網路爬蟲 - 在Yahoo!股市爬自動取多個股價

今天要介紹的工具叫做 Selenium,有做過類似網路爬蟲的人或許會常聽到這項工具,根據 wiki 的描述:

Selenium 是一個綜合性的項目,為 Web 瀏覽器的自動化提供了各種工具和依賴包。

過去我對這句話一直感覺到很困惑,主要原因就是不太理解為甚麼被稱為「綜合性」,後來我接觸到一個叫做 QA 的領域,也才明白原來還有這麼一個領域正在做所謂的「自動化測試」工作,而這項工具不僅可以用來爬蟲,更可以做為自動化測試的工具。

本篇文章主要會集中介紹使用這項工具來做網路爬蟲,之後在找一個時間來介紹怎麼樣做自動化測試。

安裝瀏覽器的 Driver - Webdriver

常見的瀏覽器基本上都有 Webdriver,可以根據自己常用的瀏覽器做選擇,會使用 Google Chrome 來做範例,如果想使用其他的瀏覽器,可以參考這個 Selenium Documentation

需要注意的地方是選擇下載 Webdriver 的版本需要和桌面版本的相同。

如何檢查桌面 Chrome 瀏覽器的版本:

只需要打開瀏覽器,點及右上角的三個點,再點擊設定,會開啟設定頁面,再選關於 Chrome 就可以看到當前版本。

Webdriver 下載頁面則選擇對應的版本即可。


下載完後並解壓縮,你會取得一個應用程式檔案名為 chromedriver,接下來我們就可以透過寫程式,來啟動這個 Driver,以及做到自動化和爬蟲的效果。

安裝 Selenium Python Package

pip3 install selenium 

只需要將 import webdriver 就可以開始啟用 selenium 的 service。

from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.webdriver.common.by import By

取得搜尋股票代號的網頁元素 XPATH

要如何找到這個欄位的 XPATH 呢? 

在瀏覽器畫面點擊右鍵來開啟「檢查」的功能,再點擊右上角有一個 select an element in the page to inspect it 的按鈕 (也可以透過快捷鍵 Ctrl + Shift + C 來啟動)。

當你指向這個欄位以後,畫面會出現一個藍色的小視窗,只需要點擊一下即可,右邊檢查網頁的畫面會直接顯示相對應的元素。




然後只需要對這個選中的元素,點擊右鍵選擇 Copy,會出現 Copy Xpath,這樣就可以取得欄位元素,接下來只需要對這個元素進行我們想要的動作,如輸入股票代碼。

既然我們已經取得該欄位的 Xpath,現在就可以在這個欄位中輸入我們要的代碼:

SEARCH_BAR = '//*[@id="ssb-search-input"]'

driver.find_element(By.XPATH, e1e.SEARCH_BAR).send_keys('2330')

如此一來,該欄位就會自動幫我們輸入台積電的股票代碼。


這邊就有兩種做法,你可以對網頁進行按 Enter 的動作,或者是選擇下方出現的內容。

我覺得直接點擊 Enter 比較符合使用者的使用邏輯,有些網站可能會出現一個搜尋按鈕,也是可以直接指定點擊按鈕即可。

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

ActionChains(driver).send_keys(Keys.ENTER).perform()

Webdriver 就會自動來對網頁點擊 Enter 的按鍵,就會進入到該股票代碼的詳細頁面。

抓取股票成交價, 開盤價, 最高, 最低, 均價

抓取股票的價位方法,就像一開始抓取輸入股票代碼欄位的方法相同。


這時候可以看到,他是一整個欄位幫你框起來,我們只需要去解析這個網頁元素,就可以得到這些數字。

取得網頁元素上的文字

可以嘗試把檢查頁面中的網頁元素給展開來看,你會看到裡面每一個元素後面都包著一個文字。


由於一開始抓到的網頁元素是比較上面的階層,但也是可以透過 .text 的指令來看到元素底下的所有文字,待會我們再進行拆分就好。

STOCK_DATA = '//*[@id="qsp-overview-realtime-info"]/div[2]/div[2]/div/ul'

driver.find_element(By.XPATH, e1e.STOCK_DATA).text
你會取得這樣的字串結果:

'成交\n455.0\n開盤\n457.5\n最高\n458.5\n最低\n455.0\n均價\n456.5\n成交金額(億)\n113.59\n昨收\n468.0\n漲跌幅\n2.78%\n漲跌\n13.0\n總量\n24,882\n昨量\n14,024\n振幅\n0.75%'

當然可以對這個字串進行解析,不過有點麻煩,畢竟從網頁檢查頁面中,可以觀察出網頁已經將每一個我們要的內容,都依照 <li> 和 <span> 來分割了。

所以只需要對最高階層的元素來往下找分類好的元素:

datas = stock_data.find_elements(By.TAG_NAME, 'li)

for i in range(len(datats)):
    print(datas[i].text)

已經知道前面五個是我們要爬的數據,所以只需要取前五次即可:

target = {
    '成交': '',
    '開盤': '',
    '最高': '',
    '最低': '',
    '均價': ''
}

for i in range(5):
    # print(datas[i].text)
    if list(target)[i] in datas[i].text:
        target[list(target)[i]] = datas[i].text.split()[1]

這樣就把我們要的資料給存下來了,剩下就看你會不會需要搜尋不同的股票代碼,然後分別另存到同一份的 Excel 檔案裡。

>>> target
{'成交': '455.0', '開盤': '457.5', '最高': '458.5', '最低': '455.0', '均價': '456.5'}

完整程式碼可以到我的 GitHub 去看看唷

張貼留言

較新的 較舊