金融大數據分析 巨量資料科學 交易策略建構 量化交易系統 動態槓桿控管
Python爬取台股籌碼資料-股權分散表
本文章將介紹取得股權分散表。
而我們使用的方式是透過爬蟲, 如果我們目前要去網站上抓取股權分散表,我們最遠的期間只能抓到一年以前的資料(集保官方網站的設計),由於是集保中心提供,所以如果強調資料正確性的讀者,可以透過集保中心網站去定期維護自己的資料。股權分散表的網頁,可以參考上一篇股權分散表的文章。
針對查詢網頁的資料進行爬蟲,而該網站無法使用靜態網頁爬取的方法,必須使用selenium的方式去進行爬蟲,而目前集保中心的歷史資料抓取期限為最近50周,本範例的做法是將特定一個商品爬取50周,selenium的爬蟲方式需要先下載瀏覽器核心,不過由於不是本文章核心要解釋的,如果有讀者有問題,可以留言告訴我,會再另外介紹selenium的爬蟲準備。
以下就開始介紹程式碼
# 載入必要的套件
import time
from bs4 import BeautifulSoup as bs
from selenium import webdriver
from selenium.webdriver.support.select import Select
import csv,random,os
# 切換工作路徑
os.chdir('放置瀏覽器核心的路徑')
如上程式碼,首先我們要切換到特定的工作路徑,該路徑底下有瀏覽器的核心檔案(chromedriver.exe)。
# 定義商品名稱
prod='0050'
如上程式碼,定義要抓取的證券代碼。
# 寫入標提列
file=open(prod+'_shareHolder.csv', "w")
file.write("日期, 證券代碼, 持股分級, 持股數量分級, 人數, 股數, 占集保庫存數比例% \n")
如上程式碼,存檔命名方式為「商品代碼_ shareHolder.csv」,撰寫檔案欄位名稱。
# 透過 selenium 進行爬蟲 找到瀏覽器核心
chrome_driver_path = r"chromedriver.exe"
# 透過無痕模式啟動
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
browser = webdriver.Chrome(executable_path=chrome_driver_path, options=chrome_options)
如上程式碼,啟動瀏覽器核心執行檔,並開啟headless模式,執行過程中不會顯示網頁UI。
# 進入集保網址
url = r"https://www.tdcc.com.tw/portal/zh/smWeb/qryStock"
browser.get(url)
time.sleep(3)
如上程式碼,潛入集保網頁取得股權分散表的網頁,接著我們透過迴圈去執行要爬取的日期。
# 集保機制是採用,選擇最近的1周至50周,所以執行1-50的迴圈
for i in range(1,51):
# 除錯機制
# 設定開啟網頁之日期 選定日期
select_1 = Select(browser.find_element(By.NAME,"scaDate"))
select_1.select_by_index(i)
time.sleep(1)
如上程式碼,進入頁面後,找到選取日期的標籤,透過select_by_index函數,從Select標籤中選擇第N個,預計從1-50,將近50周的資料爬取。
# 輸入股票代碼
browser.find_element(By.ID,"StockNo").clear()
browser.find_element(By.ID,"StockNo").send_keys(prod)
time.sleep(1)
如上程式碼,在商品名稱欄位中輸入股票代碼,使用send_keys函數。
# 模擬網頁送出查詢
browser.find_element(By.XPATH,"//tr[4]//td[1]//input[1]").click()
time.sleep(1)
如上程式碼,接著找到submit按鈕,送出,這邊是用xpath去找尋標籤的定位,在本技巧的後面會介紹xpath。
# 取得網頁原始碼
html_file = browser.page_source
# 建立beautifulSoup 解析文件
soup = bs(html_file, "lxml")
透過BeautifulSoup套件去解析我們得到的網頁內容,網頁內容是透過page_source屬性去取得。
html_date = soup.find("span", class_="font")
html_date=html_date.text
html_date=html_date.split(':')[1]
html_date=html_date.replace('年','/').replace('月','/').replace('日','')
取得我們所抓到的股權分散表日期,將格式轉換為日期格式,例如「111/03/01」。
# 找出回傳之分散表
tbody = soup.find("table", class_="table").find("tbody").find_all("tr")
# 每個股票的股權分散表的處理
for tr in tbody:
tds = tr.find_all("td")
tmp_row = []
for td in tds:
tmp_row.append(td.text)
tmp_row.insert(0, html_date)
tmp_row.insert(1, prod)
file.write(','.join(tmp_row)+'\n')
透過迴圈將每一行股權分散,都寫入特定檔案中。
# 隨機休息 5-10秒
time.sleep(random.randint(5,10))
except Exception as e:
print(prod,'有誤,請檢查程式',i)
以上是程式碼的詳細介紹,該範例檔是以0050商品為例,讀者可自行修改,程式執行檔案結果如下。
檔名:0050_shareHolder.csv
日期, 證券代碼, 持股分級, 持股數量分級, 人數, 股數, 占集保庫存數比例%
111/05/13,0050,1,1-999,308,875,78,873,694,4.57
111/05/13,0050,2,1,000-5,000,196,408,382,478,671,22.18
111/05/13,0050,3,5,001-10,000,21,581,159,959,434,9.27
111/05/13,0050,4,10,001-15,000,5,988,75,257,853,4.36
111/05/13,0050,5,15,001-20,000,2,839,50,884,610,2.95
111/05/13,0050,6,20,001-30,000,2,447,60,844,289,3.52
111/05/13,0050,7,30,001-40,000,951,33,528,136,1.94
111/05/13,0050,8,40,001-50,000,508,23,283,952,1.35
111/05/13,0050,9,50,001-100,000,780,54,193,233,3.14
111/05/13,0050,10,100,001-200,000,233,31,523,833,1.82
111/05/13,0050,11,200,001-400,000,84,23,619,620,1.37
111/05/13,0050,12,400,001-600,000,35,16,898,493,0.98
111/05/13,0050,13,600,001-800,000,12,8,541,000,0.49
111/05/13,0050,14,800,001-1,000,000,13,11,520,000,0.66
111/05/13,0050,15,1,000,001以上,71,712,593,182,41.33
111/05/13,0050,16,合 計,540,825,1,724,000,000,100.00
大家可以試試看哦,有任何問題,歡迎留言告訴我!