2018年11月5日 星期一

Python 學習筆記 : 台股資料擷取模組 twstock 測試 (一)

九月初在明儀買了一本鄧文淵工作室出版的好書, 此書有一段時間蟬聯博客來電腦類書籍暢銷排行榜第一名, 書的篇幅雖然不大, 但所談論的主題恰好都是我最感興趣的. 其實真正的好書只要說出重點即可, 厚重的書令人生畏, 因為好像都讀不完.

買書 : Python 大數據特訓班




此書第 9 章介紹的台股盤後資料擷取模組 twstock 非常好用, 它封裝了繁雜的網頁擷取細節, 提供簡潔的 API 簡化資料擷取程序, 方便開發者從證交所 (TWSE) 與櫃買中心 (TPEX) 擷取收盤資料, 對於追蹤台股投資標的與歷史回測可節省不少時間.

因為是第三方套件, 須先用 pip 安裝 :

pip3 install twstock

如果因為防火牆無法用 pip 安裝, 可先到 Pypi 網站下載 whl 檔離線安裝 :

https://pypi.org/project/twstock/#files

D:\Python>pip3 install twstock-1.1.0-py3-none-any.whl
Processing d:\python\twstock-1.1.0-py3-none-any.whl
Requirement already satisfied: requests in c:\users\cht\.thonny\bundledpython36\lib\site-packages (f
rom twstock==1.1.0) (2.19.1)
Requirement already satisfied: idna<2.8,>=2.5 in c:\users\cht\.thonny\bundledpython36\lib\site-packa
ges (from requests->twstock==1.1.0) (2.7)
Requirement already satisfied: urllib3<1.24,>=1.21.1 in c:\users\cht\.thonny\bundledpython36\lib\sit
e-packages (from requests->twstock==1.1.0) (1.23)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\cht\.thonny\bundledpython36\lib\site-p
ackages (from requests->twstock==1.1.0) (2018.4.16)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\cht\.thonny\bundledpython36\lib\sit
e-packages (from requests->twstock==1.1.0) (3.0.4)
Installing collected packages: twstock
Successfully installed twstock-1.1.0

從安裝過程可知, twstock 主要使用了 requests 與 urllib3 進行網頁擷取工作. 此套件作者為 louilu, 除了 twstock 外, 他在 Pypi 上還有好幾個專案, 參考 :

# Pypi : louilu

twstock 寄存在 Github 上, 裡面有其詳細 API 使用說明 :

https://github.com/mlouielu/twstock
https://twstock.readthedocs.io/zh_TW/latest/ (中文文件系統)

另外作者還有一個 stocker 專案用來觀察個股是否值得買進, 參考 GitHub :

https://github.com/mlouielu/stocker

此套件的主角-網頁擷取程式放在 stock.py 裡, 可一窺網頁爬蟲的撰寫技巧 :

https://github.com/mlouielu/twstock/blob/master/twstock/stock.py

以下就參考 GitHub 與書本說明, 實際測試 twstock 模組的功能. 使用前須先匯入 twstock :

import twstock 

然後呼叫 Stock 類別的建構子 twstock.Stock() 並傳入股票代號會傳回一個 Stock 物件, 例如 :

>>> import twstock 
>>> tw2330=twstock.Stock("2330") 
>>> type(tw2330) 
<class 'twstock.stock.Stock'>   

也可以直接匯入 Stock 類別以減省輸入 twstock 套件名稱 :

>>> from twstock import Stock 
>>> tw2330=Stock("2330") 
>>> type(tw2330) 
<class 'twstock.stock.Stock'>

查詢 Stock 物件的 price 屬性會傳回最近 31 個交易日的收盤價串列, 最後一個元素即前一個交易日收盤價, 例如 :

>>> tw2330.price
[260.0, 261.5, 263.5, 263.5, 265.0, 262.5, 263.0, 257.5, 260.0, 254.0, 250.0, 243.5, 244.0, 227.5, 237.0, 230.5, 237.0, 238.5, 236.5, 236.0, 237.0, 230.0, 229.5, 219.5, 221.0, 222.5, 223.0, 234.0, 235.5, 236.5, 235.0]
>>> tw2330.price[0]    # 31 日前收盤價
260.0
>>> tw2330.price[30]   #前一交易日收盤價
235.0

因為 price 傳回值為串列, 因此可用串列切片取得最近 5 日收盤價 :

>>> tw2330.price[-5:]      #近五日收盤價
[223.0, 234.0, 235.5, 236.5, 235.0]

除了 price 外, Stock 物件還有 open, high, low, close, fetch() 等屬性與方法, 可用內建函數 dir() 查詢, 例如 :

>>> dir(tw2330)     #查詢 Stock 物件 tw2330 內容
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_month_year_iter', 'capacity', 'change', 'close', 'continuous', 'data', 'date', 'fetch', 'fetch_31', 'fetch_from', 'fetcher', 'high', 'low', 'ma_bias_ratio', 'ma_bias_ratio_pivot', 'moving_average', 'open', 'price', 'raw_data', 'sid', 'transaction', 'turnover']

其中名稱含有兩個底線的是類別內部屬性或方法, 沒有底線的才是類別對外的 API. 但要如何區別哪些是屬性, 哪些是方法呢? 可在串列推導式中使用內建函數 getattr() 查詢, 例如 :

>>> [(name, type(getattr(tw2330, name))) for name in dir(tw2330)] 
[('__class__', <class 'type'>), ('__delattr__', <class 'method-wrapper'>), ('__dict__', <class 'dict'>), ('__dir__', <class 'builtin_function_or_method'>), ('__doc__', <class 'NoneType'>), ('__eq__', <class 'method-wrapper'>), ('__format__', <class 'builtin_function_or_method'>), ('__ge__', <class 'method-wrapper'>), ('__getattribute__', <class 'method-wrapper'>), ('__gt__', <class 'method-wrapper'>), ('__hash__', <class 'method-wrapper'>), ('__init__', <class 'method'>), ('__init_subclass__', <class 'builtin_function_or_method'>), ('__le__', <class 'method-wrapper'>), ('__lt__', <class 'method-wrapper'>), ('__module__', <class 'str'>), ('__ne__', <class 'method-wrapper'>), ('__new__', <class 'builtin_function_or_method'>), ('__reduce__', <class 'builtin_function_or_method'>), ('__reduce_ex__', <class 'builtin_function_or_method'>), ('__repr__', <class 'method-wrapper'>), ('__setattr__', <class 'method-wrapper'>), ('__sizeof__', <class 'builtin_function_or_method'>), ('__str__', <class 'method-wrapper'>), ('__subclasshook__', <class 'builtin_function_or_method'>), ('__weakref__', <class 'NoneType'>), ('_month_year_iter', <class 'method'>), ('capacity', <class 'list'>), ('change', <class 'list'>), ('close', <class 'list'>), ('continuous', <class 'method'>), ('data', <class 'list'>), ('date', <class 'list'>), ('fetch', <class 'method'>), ('fetch_31', <class 'method'>), ('fetch_from', <class 'method'>), ('fetcher', <class 'twstock.stock.TWSEFetcher'>), ('high', <class 'list'>), ('low', <class 'list'>), ('ma_bias_ratio', <class 'method'>), ('ma_bias_ratio_pivot', <class 'method'>), ('moving_average', <class 'method'>), ('open', <class 'list'>), ('price', <class 'list'>), ('raw_data', <class 'list'>), ('sid', <class 'str'>), ('transaction', <class 'list'>), ('turnover', <class 'list'>)]

其中標示 'list' 者為屬性, 標示 'method' 者為方法, 參考 :

Python - dir() - how can I differentiate between functions/method and simple attributes?

Stock 物件的屬性如下表 :

 Stock 物件的屬性 說明
 price 傳回近 31 天的收盤價 (單位=元) 串列
 capacity 傳回近 31 天的成交量 (單位=股) 串列
 turnover 傳回近 31 天的成交金額 (單位=元) 串列
 transaction 傳回近 31 天的成交筆數 (單位=筆) 串列
 close 傳回近 31 天的收盤價 (單位=元) 串列 (同 price)
 change 傳回近 31 天收盤價的漲跌幅 (單位=元) 串列 
 open  傳回近 31 天的開盤價 (單位=元) 串列
 low 傳回近 31 天的最低價 (單位=元) 串列
 high 傳回近 31 天的最高價 (單位=元) 串列
 date 傳回近 31 天的交易日期 datetime 物件串列
 sid 傳回股票代號字串
 data 傳回近 31 天的 Stock 物件全部資料內容 (Data 物件) 串列
 raw_data 傳回近 31 天所擷取之原始資料串列

這些屬性除了 sid 傳回字串外, 其他均傳回串列, 其中 close 屬性與 price 一樣都是傳回最近 31 個交易日的收盤價; 其他如 open (開盤價), low (最低價), high (最高價), change (漲跌幅) 等都是傳回一個串列, 例如 :

>>> tw2330.sid 
'2330'
>>> tw2330.price 
[260.0, 261.5, 263.5, 263.5, 265.0, 262.5, 263.0, 257.5, 260.0, 254.0, 250.0, 243.5, 244.0, 227.5, 237.0, 230.5, 237.0, 238.5, 236.5, 236.0, 237.0, 230.0, 229.5, 219.5, 221.0, 222.5, 223.0, 234.0, 235.5, 236.5, 235.0]
>>> tw2330.close 
[260.0, 261.5, 263.5, 263.5, 265.0, 262.5, 263.0, 257.5, 260.0, 254.0, 250.0, 243.5, 244.0, 227.5, 237.0, 230.5, 237.0, 238.5, 236.5, 236.0, 237.0, 230.0, 229.5, 219.5, 221.0, 222.5, 223.0, 234.0, 235.5, 236.5, 235.0]
>>> tw2330.change
[2.0, 1.5, 2.0, 0.0, 1.5, -2.5, 0.5, -5.5, 2.5, -6.0, -4.0, -6.5, 0.5, -16.5, 9.5, -6.5, 6.5, 1.5, -2.0, -0.5, 1.0, -7.0, -0.5, -10.0, 1.5, 1.5, 0.5, 11.0, 1.5, 1.0, -1.5]
>>> tw2330.open
[261.5, 261.5, 261.5, 263.0, 264.0, 266.0, 262.0, 262.0, 257.5, 257.0, 250.0, 245.5, 243.5, 233.5, 231.0, 234.0, 229.5, 241.5, 238.0, 231.0, 232.5, 232.0, 230.0, 220.5, 223.0, 223.0, 221.0, 228.0, 236.0, 236.5, 233.0]
>>> tw2330.low 
[257.5, 258.0, 260.5, 261.0, 262.0, 260.0, 261.0, 257.0, 257.0, 254.0, 248.5, 241.0, 242.0, 227.0, 229.0, 230.5, 229.0, 238.0, 235.5, 230.0, 231.5, 230.0, 227.0, 219.5, 217.0, 221.0, 220.5, 228.0, 233.0, 233.5, 232.0]
>>> tw2330.high 
[261.5, 261.5, 264.0, 263.5, 266.0, 266.0, 264.0, 263.0, 260.0, 257.5, 253.0, 246.5, 245.0, 233.5, 237.0, 234.0, 237.0, 243.0, 239.0, 236.5, 238.0, 234.0, 231.0, 222.0, 224.0, 224.0, 225.0, 234.0, 237.0, 236.5, 235.5]

有三個屬性是量能資訊 : capacity (成交股數), turnover (成交金額), 以及 transaction (成交筆數), 例如 :

>>> tw2330.capacity 
[35577071, 36500974, 24978062, 25061115, 38495371, 39645486, 22409380, 38391491, 25228536, 38009727, 40396660, 51083958, 28933345, 96033657, 54439769, 46471280, 39129077, 42887858, 27793430, 29648460, 29275777, 36757745, 45480950, 75524118, 54073644, 18463792, 29085931, 59933201, 44514797, 30785361, 25463065]
>>> tw2330.turnover 
[9225009310, 9510363894, 6552894296, 6577367245, 10185827315, 10412455506, 5882532290, 9926505357, 6527393860, 9690178362, 10101451270, 12426290240, 7051600725, 22115862239, 12650322522, 10766953220, 9155829047, 10318955161, 6587887632, 6927405460, 6872467149, 8538586595, 10426514872, 16643542368, 11941421696, 4107663616, 6487213284, 13844478353, 10480329245, 7249667833, 5960958275]
>>> tw2330.transaction 
[9444, 10159, 10082, 7007, 11536, 13060, 11914, 17095, 9992, 15094, 16031, 20745, 11743, 37543, 17980, 16558, 15182, 17550, 10599, 12378, 10384, 13071, 17339, 27514, 17106, 7679, 8574, 19183, 11435, 11223, 6990]

屬性 data 傳回近 31 天的交易資料, 每日資料被封裝在 Data 物件中以串列傳回, 例如 :

>>> tw2330.data 
[Data(date=datetime.datetime(2018, 9, 20, 0, 0), capacity=35577071, turnover=9225009310, open=261.5, high=261.5, low=257.5, close=260.0, change=2.0, transaction=9444), Data(date=datetime.datetime(2018, 9, 21, 0, 0), capacity=36500974, turnover=9510363894, open=261.5, high=261.5, low=258.0, close=261.5, change=1.5, transaction=10159), Data(date=datetime.datetime(2018, 9, 25, 0, 0), capacity=24978062, turnover=6552894296, open=261.5, high=264.0, low=260.5, close=263.5, change=2.0, transaction=10082), Data(date=datetime.datetime(2018, 9, 26, 0, 0), capacity=25061115, turnover=6577367245, open=263.0, high=263.5, low=261.0, close=263.5, change=0.0, transaction=7007), Data(date=datetime.datetime(2018, 9, 27, 0, 0), capacity=38495371, turnover=10185827315, open=264.0, high=266.0, low=262.0, close=265.0, change=1.5, transaction=11536), Data(date=datetime.datetime(2018, 9, 28, 0, 0), capacity=39645486, turnover=10412455506, open=266.0, high=266.0, low=260.0, close=262.5, change=-2.5, transaction=13060), Data(date=datetime.datetime(2018, 10, 1, 0, 0), capacity=22409380, turnover=5882532290, open=262.0, high=264.0, low=261.0, close=263.0, change=0.5, transaction=11914), Data(date=datetime.datetime(2018, 10, 2, 0, 0), capacity=38391491, turnover=9926505357, open=262.0, high=263.0, low=257.0, close=257.5, change=-5.5, transaction=17095), Data(date=datetime.datetime(2018, 10, 3, 0, 0), capacity=25228536, turnover=6527393860, open=257.5, high=260.0, low=257.0, close=260.0, change=2.5, transaction=9992), Data(date=datetime.datetime(2018, 10, 4, 0, 0), capacity=38009727, turnover=9690178362, open=257.0, high=257.5, low=254.0, close=254.0, change=-6.0, transaction=15094), Data(date=datetime.datetime(2018, 10, 5, 0, 0), capacity=40396660, turnover=10101451270, open=250.0, high=253.0, low=248.5, close=250.0, change=-4.0, transaction=16031), Data(date=datetime.datetime(2018, 10, 8, 0, 0), capacity=51083958, turnover=12426290240, open=245.5, high=246.5, low=241.0, close=243.5, change=-6.5, transaction=20745), Data(date=datetime.datetime(2018, 10, 9, 0, 0), capacity=28933345, turnover=7051600725, open=243.5, high=245.0, low=242.0, close=244.0, change=0.5, transaction=11743), Data(date=datetime.datetime(2018, 10, 11, 0, 0), capacity=96033657, turnover=22115862239, open=233.5, high=233.5, low=227.0, close=227.5, change=-16.5, transaction=37543), Data(date=datetime.datetime(2018, 10, 12, 0, 0), capacity=54439769, turnover=12650322522, open=231.0, high=237.0, low=229.0, close=237.0, change=9.5, transaction=17980), Data(date=datetime.datetime(2018, 10, 15, 0, 0), capacity=46471280, turnover=10766953220, open=234.0, high=234.0, low=230.5, close=230.5, change=-6.5, transaction=16558), Data(date=datetime.datetime(2018, 10, 16, 0, 0), capacity=39129077, turnover=9155829047, open=229.5, high=237.0, low=229.0, close=237.0, change=6.5, transaction=15182), Data(date=datetime.datetime(2018, 10, 17, 0, 0), capacity=42887858, turnover=10318955161, open=241.5, high=243.0, low=238.0, close=238.5, change=1.5, transaction=17550), Data(date=datetime.datetime(2018, 10, 18, 0, 0), capacity=27793430, turnover=6587887632, open=238.0, high=239.0, low=235.5, close=236.5, change=-2.0, transaction=10599), Data(date=datetime.datetime(2018, 10, 19, 0, 0), capacity=29648460, turnover=6927405460, open=231.0, high=236.5, low=230.0, close=236.0, change=-0.5, transaction=12378), Data(date=datetime.datetime(2018, 10, 22, 0, 0), capacity=29275777, turnover=6872467149, open=232.5, high=238.0, low=231.5, close=237.0, change=1.0, transaction=10384), Data(date=datetime.datetime(2018, 10, 23, 0, 0), capacity=36757745, turnover=8538586595, open=232.0, high=234.0, low=230.0, close=230.0, change=-7.0, transaction=13071), Data(date=datetime.datetime(2018, 10, 24, 0, 0), capacity=45480950, turnover=10426514872, open=230.0, high=231.0, low=227.0, close=229.5, change=-0.5, transaction=17339), Data(date=datetime.datetime(2018, 10, 25, 0, 0), capacity=75524118, turnover=16643542368, open=220.5, high=222.0, low=219.5, close=219.5, change=-10.0, transaction=27514), Data(date=datetime.datetime(2018, 10, 26, 0, 0), capacity=54073644, turnover=11941421696, open=223.0, high=224.0, low=217.0, close=221.0, change=1.5, transaction=17106), Data(date=datetime.datetime(2018, 10, 29, 0, 0), capacity=18463792, turnover=4107663616, open=223.0, high=224.0, low=221.0, close=222.5, change=1.5, transaction=7679), Data(date=datetime.datetime(2018, 10, 30, 0, 0), capacity=29085931, turnover=6487213284, open=221.0, high=225.0, low=220.5, close=223.0, change=0.5, transaction=8574), Data(date=datetime.datetime(2018, 10, 31, 0, 0), capacity=59933201, turnover=13844478353, open=228.0, high=234.0, low=228.0, close=234.0, change=11.0, transaction=19183), Data(date=datetime.datetime(2018, 11, 1, 0, 0), capacity=44514797, turnover=10480329245, open=236.0, high=237.0, low=233.0, close=235.5, change=1.5, transaction=11435), Data(date=datetime.datetime(2018, 11, 2, 0, 0), capacity=30785361, turnover=7249667833, open=236.5, high=236.5, low=233.5, close=236.5, change=1.0, transaction=11223), Data(date=datetime.datetime(2018, 11, 5, 0, 0), capacity=25463065, turnover=5960958275, open=233.0, high=235.5, low=232.0, close=235.0, change=-1.5, transaction=6990)]

屬性 raw_data 是 twstock 套件擷取證交所網頁近 31 個交易日之原始資料 :

>>> tw2330.raw_data 
[{'stat': 'OK', 'date': '20180901', 'title': '107年09月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'data': [Data(date=datetime.datetime(2018, 9, 3, 0, 0), capacity=34510555, turnover=8901193266, open=259.0, high=260.0, low=256.5, close=257.0, change=1.0, transaction=11442), Data(date=datetime.datetime(2018, 9, 4, 0, 0), capacity=41455615, turnover=10654493061, open=258.5, high=259.5, low=255.5, close=257.5, change=0.5, transaction=9069), Data(date=datetime.datetime(2018, 9, 5, 0, 0), capacity=52706459, turnover=13833360422, open=260.0, high=264.5, low=259.0, close=264.0, change=6.5, transaction=16421), Data(date=datetime.datetime(2018, 9, 6, 0, 0), capacity=39779488, turnover=10467251488, open=268.0, high=268.0, low=261.0, close=261.0, change=-3.0, transaction=11996), Data(date=datetime.datetime(2018, 9, 7, 0, 0), capacity=44746728, turnover=11753033262, open=263.0, high=264.0, low=260.5, close=264.0, change=3.0, transaction=15015), Data(date=datetime.datetime(2018, 9, 10, 0, 0), capacity=62851599, turnover=16669866076, open=266.5, high=266.5, low=262.5, close=264.5, change=0.5, transaction=15504), Data(date=datetime.datetime(2018, 9, 11, 0, 0), capacity=44981276, turnover=11709484991, open=263.0, high=263.5, low=258.0, close=260.0, change=-4.5, transaction=14768), Data(date=datetime.datetime(2018, 9, 12, 0, 0), capacity=38415965, turnover=9987682900, open=261.0, high=262.0, low=258.0, close=260.5, change=0.5, transaction=12104), Data(date=datetime.datetime(2018, 9, 13, 0, 0), capacity=37959180, turnover=9721989110, open=260.0, high=260.0, low=253.5, close=255.0, change=-5.5, transaction=14987), Data(date=datetime.datetime(2018, 9, 14, 0, 0), capacity=40034219, turnover=10379404959, open=257.0, high=261.5, low=257.0, close=261.0, change=6.0, transaction=15690), Data(date=datetime.datetime(2018, 9, 17, 0, 0), capacity=25041358, turnover=6483537091, open=262.5, high=262.5, low=257.0, close=258.0, change=-3.0, transaction=10710), Data(date=datetime.datetime(2018, 9, 18, 0, 0), capacity=34381152, turnover=8771502830, open=256.5, high=257.0, low=254.0, close=254.5, change=-3.5, transaction=11097), Data(date=datetime.datetime(2018, 9, 19, 0, 0), capacity=69978711, turnover=18074954749, open=258.0, high=260.0, low=257.0, close=258.0, change=3.5, transaction=14056), Data(date=datetime.datetime(2018, 9, 20, 0, 0), capacity=35577071, turnover=9225009310, open=261.5, high=261.5, low=257.5, close=260.0, change=2.0, transaction=9444), Data(date=datetime.datetime(2018, 9, 21, 0, 0), capacity=36500974, turnover=9510363894, open=261.5, high=261.5, low=258.0, close=261.5, change=1.5, transaction=10159), Data(date=datetime.datetime(2018, 9, 25, 0, 0), capacity=24978062, turnover=6552894296, open=261.5, high=264.0, low=260.5, close=263.5, change=2.0, transaction=10082), Data(date=datetime.datetime(2018, 9, 26, 0, 0), capacity=25061115, turnover=6577367245, open=263.0, high=263.5, low=261.0, close=263.5, change=0.0, transaction=7007), Data(date=datetime.datetime(2018, 9, 27, 0, 0), capacity=38495371, turnover=10185827315, open=264.0, high=266.0, low=262.0, close=265.0, change=1.5, transaction=11536), Data(date=datetime.datetime(2018, 9, 28, 0, 0), capacity=39645486, turnover=10412455506, open=266.0, high=266.0, low=260.0, close=262.5, change=-2.5, transaction=13060)], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價、鉅額交易,不含拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。']}, {'stat': 'OK', 'date': '20181001', 'title': '107年10月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'data': [Data(date=datetime.datetime(2018, 10, 1, 0, 0), capacity=22409380, turnover=5882532290, open=262.0, high=264.0, low=261.0, close=263.0, change=0.5, transaction=11914), Data(date=datetime.datetime(2018, 10, 2, 0, 0), capacity=38391491, turnover=9926505357, open=262.0, high=263.0, low=257.0, close=257.5, change=-5.5, transaction=17095), Data(date=datetime.datetime(2018, 10, 3, 0, 0), capacity=25228536, turnover=6527393860, open=257.5, high=260.0, low=257.0, close=260.0, change=2.5, transaction=9992), Data(date=datetime.datetime(2018, 10, 4, 0, 0), capacity=38009727, turnover=9690178362, open=257.0, high=257.5, low=254.0, close=254.0, change=-6.0, transaction=15094), Data(date=datetime.datetime(2018, 10, 5, 0, 0), capacity=40396660, turnover=10101451270, open=250.0, high=253.0, low=248.5, close=250.0, change=-4.0, transaction=16031), Data(date=datetime.datetime(2018, 10, 8, 0, 0), capacity=51083958, turnover=12426290240, open=245.5, high=246.5, low=241.0, close=243.5, change=-6.5, transaction=20745), Data(date=datetime.datetime(2018, 10, 9, 0, 0), capacity=28933345, turnover=7051600725, open=243.5, high=245.0, low=242.0, close=244.0, change=0.5, transaction=11743), Data(date=datetime.datetime(2018, 10, 11, 0, 0), capacity=96033657, turnover=22115862239, open=233.5, high=233.5, low=227.0, close=227.5, change=-16.5, transaction=37543), Data(date=datetime.datetime(2018, 10, 12, 0, 0), capacity=54439769, turnover=12650322522, open=231.0, high=237.0, low=229.0, close=237.0, change=9.5, transaction=17980), Data(date=datetime.datetime(2018, 10, 15, 0, 0), capacity=46471280, turnover=10766953220, open=234.0, high=234.0, low=230.5, close=230.5, change=-6.5, transaction=16558), Data(date=datetime.datetime(2018, 10, 16, 0, 0), capacity=39129077, turnover=9155829047, open=229.5, high=237.0, low=229.0, close=237.0, change=6.5, transaction=15182), Data(date=datetime.datetime(2018, 10, 17, 0, 0), capacity=42887858, turnover=10318955161, open=241.5, high=243.0, low=238.0, close=238.5, change=1.5, transaction=17550), Data(date=datetime.datetime(2018, 10, 18, 0, 0), capacity=27793430, turnover=6587887632, open=238.0, high=239.0, low=235.5, close=236.5, change=-2.0, transaction=10599), Data(date=datetime.datetime(2018, 10, 19, 0, 0), capacity=29648460, turnover=6927405460, open=231.0, high=236.5, low=230.0, close=236.0, change=-0.5, transaction=12378), Data(date=datetime.datetime(2018, 10, 22, 0, 0), capacity=29275777, turnover=6872467149, open=232.5, high=238.0, low=231.5, close=237.0, change=1.0, transaction=10384), Data(date=datetime.datetime(2018, 10, 23, 0, 0), capacity=36757745, turnover=8538586595, open=232.0, high=234.0, low=230.0, close=230.0, change=-7.0, transaction=13071), Data(date=datetime.datetime(2018, 10, 24, 0, 0), capacity=45480950, turnover=10426514872, open=230.0, high=231.0, low=227.0, close=229.5, change=-0.5, transaction=17339), Data(date=datetime.datetime(2018, 10, 25, 0, 0), capacity=75524118, turnover=16643542368, open=220.5, high=222.0, low=219.5, close=219.5, change=-10.0, transaction=27514), Data(date=datetime.datetime(2018, 10, 26, 0, 0), capacity=54073644, turnover=11941421696, open=223.0, high=224.0, low=217.0, close=221.0, change=1.5, transaction=17106), Data(date=datetime.datetime(2018, 10, 29, 0, 0), capacity=18463792, turnover=4107663616, open=223.0, high=224.0, low=221.0, close=222.5, change=1.5, transaction=7679), Data(date=datetime.datetime(2018, 10, 30, 0, 0), capacity=29085931, turnover=6487213284, open=221.0, high=225.0, low=220.5, close=223.0, change=0.5, transaction=8574), Data(date=datetime.datetime(2018, 10, 31, 0, 0), capacity=59933201, turnover=13844478353, open=228.0, high=234.0, low=228.0, close=234.0, change=11.0, transaction=19183)], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價、鉅額交易,不含拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。']}, {'stat': 'OK', 'date': '20181101', 'title': '107年11月 2330 台積電           各日成交資訊', 'fields': ['日期', '成交股數', '成交金額', '開盤價', '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數'], 'data': [Data(date=datetime.datetime(2018, 11, 1, 0, 0), capacity=44514797, turnover=10480329245, open=236.0, high=237.0, low=233.0, close=235.5, change=1.5, transaction=11435), Data(date=datetime.datetime(2018, 11, 2, 0, 0), capacity=30785361, turnover=7249667833, open=236.5, high=236.5, low=233.5, close=236.5, change=1.0, transaction=11223), Data(date=datetime.datetime(2018, 11, 5, 0, 0), capacity=25463065, turnover=5960958275, open=233.0, high=235.5, low=232.0, close=235.0, change=-1.5, transaction=6990)], 'notes': ['符號說明:+/-/X表示漲/跌/不比價', '當日統計資訊含一般、零股、盤後定價,不含鉅額、拍賣、標購。', 'ETF證券代號第六碼為K、M、S、C者,表示該ETF以外幣交易。']}]

參考 :

# GoodInfo 台灣股市資訊網
CMoney 大盤走勢圖
證交所本國上市證券國際證券辨識號碼一覽表


2019-09-23 補充 :

twstock 已更新至 1.3.2 版 :

C:\Users\User>pip3 install twstock
Collecting twstock
  Downloading https://files.pythonhosted.org/packages/38/a0/61e6b65093a7564cb8e34aea54de28113bfe24409fb05e173360fbf5a35d/twstock-1.3.1-py3-none-any.whl (1.9MB)
Requirement already satisfied: requests in c:\python37\lib\site-packages (from twstock) (2.21.0)
Requirement already satisfied: idna<2.9,>=2.5 in c:\python37\lib\site-packages (from requests->twstock) (2.8)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in c:\python37\lib\site-packages (from requests->twstock) (1.24.1)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\python37\lib\site-packages (from requests->twstock) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in c:\python37\lib\site-packages (from requests->twstock) (2018.11.29)
Installing collected packages: twstock
Successfully installed twstock-1.3.1

可見它是用 urllib3 去抓資料的. 但還需要再安裝 lxml 這個套件才行, 否則 import twstock 時會報出少了 'lxml' 的錯誤訊息 :

C:\Users\User>pip3 install lxml
Collecting lxml
  Downloading https://files.pythonhosted.org/packages/bc/87/c3cecadcb5d7924cd71724b177343149cfc3609a89b197a991ac8593ed8c/lxml-4.4.1-cp37-cp37m-win_amd64.whl (3.7MB)
Installing collected packages: lxml
Successfully installed lxml-4.4.1

這就很奇怪, 照理說線上安裝都會自動安裝相依模組才對, 可能少了一張表.

沒有留言 :