Python+Tkinter制作股票數(shù)據(jù)抓取小程序
在前面的文章中,我們一起學(xué)習(xí)了如何通過 Python 抓取東方財富網(wǎng)的實時股票數(shù)據(jù),鏈接如下
今天我們就在這個基礎(chǔ)上,實現(xiàn)一個 Tkinter GUI 程序,完成無代碼股票抓取!
首先對于 Tkinter 相信大家都是比較了解的,如果有小伙伴對于 Tkinter 的相關(guān)用法不是特別熟悉的話,可以看如下文章
首先我們先看一下 GUI 程序的最終效果
該程序共分三個區(qū)域:
- 個股查詢:用于查詢某只股票的數(shù)據(jù),可以查詢1天或者多天數(shù)據(jù)
- 批量查詢:查詢某個交易所所有股票的數(shù)據(jù)
- 日志區(qū)域:打印抓取信息
下面我們就來看看該如何從頭完成這個 GUI 程序
程序布局
首先就是程序布局,這里我們使用了 ttkbootstrap
庫來美化整體程序
程序初始化部分
import?ttkbootstrap?as?ttk from?ttkbootstrap.constants?import?* import?tkinter.messagebox?as?messbox class?MainCreator(ttk.Window): ????def?__init__(self): ????????super().__init__("股票抓取工具",?themename="solar",?resizable=(False,?False)) ????????self.configure_frame?=?ttk.Frame(self,?padding=(10,?10,?5,?10)) ????????self.configure_frame.pack(side=LEFT,?fill=BOTH,?expand=YES) ????????self.demo_frame?=?ttk.Frame(self,?padding=(5,?10,?10,?10)) ????????self.demo_frame.pack(side=LEFT,?fill=BOTH,?expand=YES)
程序布局部分
????def?create_frame(self): ????????"""Create?all?the?frame?widgets""" ????????container?=?ttk.Frame(self) ????????container.pack(side=LEFT,?fill=BOTH,?expand=YES,?padx=5) ????????color_group?=?ttk.Labelframe( ????????????master=container,?text="個股查詢",?padding=10 ????????) ????????color_group.pack(fill=X,?side=TOP) ????????en_command?=?super().register(self.en_validate) ????????self.en0?=?ttk.Entry(color_group,?width=5,?text='',?bootstyle='warning', ?????????????????????????????validate='key',?validatecommand=(en_command,?'%P')) ????????self.en0.insert('0',?1) ????????self.en0.config(state=DISABLED) ????????...
總體上來說,我們所有的組件都是從 ttk 當(dāng)中實例化的,也就是直接復(fù)用了庫 ttkbootstrap
的相關(guān)美化功能,使得我們的程序看起來更加高級美觀
抓取與保存功能
下面我們編寫股票抓取代碼和對應(yīng)的保存代碼
股票抓取
def?get_A_mins(code): ????if?code.startswith("3")?or?code.startswith("0"): ????????url?=?shang_A_url.replace("%s",?code) ????elif?code.startswith("6"): ????????url?=?shen_A_url.replace("%s",?code) ????else: ????????return?False ????res?=?requests.get(url) ????result?=?res.text.split("cb_1659146437934_51841953")[1].split("(")[1].split(");")[0] ????result_json?=?json.loads(result) ????stock_data?=?result_json['data'] ????return?stock_data def?get_A_days(code): ????if?code.startswith("3")?or?code.startswith("0"): ????????url?=?shang_A_days.replace("%s",?code) ????elif?code.startswith("6"): ????????url?=?shen_A_days.replace("%s",?code) ????else: ????????return?False ????res?=?requests.get(url) ????result?=?res.text.split("cb_1659171393020_15037673")[1].split("(")[1].split(");")[0] ????result_json?=?json.loads(result) ????stock_data?=?result_json['data'] ????return?stock_data def?get_hsj(date): ????total_data?=?[] ????try: ????????for?i?in?range(1,?5): ????????????res?=?requests.get(hsj_url.replace("%s",?str(i))) ????????????result?=?res.text.split("jQuery112402508937289440778_1658838703304")[1].split("(")[1].split(");")[0] ????????????result_json?=?json.loads(result) ????????????stock_data?=?result_json['data'] ????????????if?stock_data: ????????????????total_data.append(stock_data) ????????????????saveFunc.save_data_hsj(stock_data['diff'],?date) ????????????else: ????????????????return?total_data ????????return?total_data ????except?Exception?as?e: ????????return?False def?get_Center(): ????total_data?=?[] ????for?i?in?range(1,?20): ????????res?=?requests.get(center_url.replace("%s",?str(i))) ????????result?=?res.text.split("jQuery112404177389105264733_1659176039486")[1].split("(")[1].split(");")[0] ????????result_json?=?json.loads(result) ????????center_data?=?result_json['data'] ????????if?center_data: ????????????total_data.append(center_data) ????????else: ????????????return?total_data def?get_shang_A(): ????pass def?get_shen_A(): ????pass def?get_bei_A(): ????pass
股票代碼分為上交所,深交所和北交所以及大盤行情數(shù)據(jù),所以我們分別編寫函數(shù)進行處理
數(shù)據(jù)保存
import?os def?save_data_mins(data,?date): ????Code?=?data['code'] ????Name?=?data['name'] ????if?not?os.path.exists(r"stock_data_%s_%s_%s_mins.csv"?%?(Code,?Name,?date)): ????????with?open("stock_data_%s_%s_%s_mins.csv"?%?(Code,?Name,?date),?"a+",?encoding='utf-8')?as?f: ????????????f.write("時間,最新價,成交量(手),成交額\n") ????????????for?i?in?data['trends']: ????????????????i_list?=?i.split(",") ????????????????time?=?i_list[0] ????????????????price?=?i_list[2] ????????????????mount?=?i_list[5] ????????????????count?=?i_list[6] ????????????????row?=?'{},{},{},{}'.format( ????????????????????time,price,mount,count) ????????????????f.write(row) ????????????????f.write('\n') ????else: ????????... def?save_data_days(data,?days): ????print(days) ????Code?=?data['code'] ????Name?=?data['name'] ????if?not?os.path.exists(r"stock_data_%s_%s_days.csv"?%?(Code,?Name)): ????????with?open("stock_data_%s_%s_days.csv"?%?(Code,?Name),?"a+",?encoding='utf-8')?as?f: ????????????f.write("時間,開盤價,收盤價,最高價,最低價,成交量(手),成交額,振幅,漲跌幅,漲跌額,換手率\n") ????????????for?i?in?data["klines"][::-1][:int(days)]: ????????????????i_list?=?i.split(",") ????????????????time?=?i_list[0] ????????????????Open?=?i_list[1] ????????????????close?=?i_list[2] ????????????????heigh?=?i_list[3] ????????????????low?=?i_list[4] ????????????????mount?=?i_list[5] ????????????????count?=?i_list[6] ????????????????amplitude?=?i_list[7] ????????????????changePercent?=?i_list[8] ????????????????change?=?i_list[9] ????????????????turnoverRate?=?i_list[10] ????????????????row?=?'{},{},{},{},{},{},{},{},{},{},{}'.format( ????????????????????time,Open,close,heigh,low,mount,count,amplitude,changePercent,change,turnoverRate) ????????????????f.write(row) ????????????????f.write('\n') ????else: ????????... def?save_data_hsj(data,?date): ????if?not?os.path.exists(r'stock_data_%s.csv'?%?date): ????????with?open("stock_data_%s.csv"?%?date,?"a+",?encoding='utf-8')?as?f: ????????????f.write("股票代碼,股票名稱,最新價,漲跌幅,漲跌額,成交量(手),成交額,振幅,換手率,市盈率,量比,最高,最低,今開,昨收,市凈率\n") ????????????for?i?in?data: ????????????????Code?=?i["f12"] ????????????????Name?=?i["f14"] ????????????????Close?=?i['f2'] ????????????????ChangePercent?=?i["f3"] ????????????????Change?=?i['f4'] ????????????????Volume?=?i['f5'] ????????????????Amount?=?i['f6'] ????????????????Amplitude?=?i['f7'] ????????????????TurnoverRate?=?i['f8'] ????????????????PERation?=?i['f9'] ????????????????VolumeRate?=?i['f10'] ????????????????Hign?=?i['f15'] ????????????????Low?=?i['f16'] ????????????????Open?=?i['f17'] ????????????????PreviousClose?=?i['f18'] ????????????????PB?=?i['f22'] ????????????????row?=?'{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}'.format( ????????????????????Code,Name,Close,ChangePercent,Change,Volume,Amount,Amplitude, ????????????????????TurnoverRate,PERation,VolumeRate,Hign,Low,Open,PreviousClose,PB) ????????????????f.write(row) ????????????????f.write('\n') ????else: ????????... def?save_data_center(): ????pass def?save_data_shang_A(): ????pass
添加功能
接下來就是為布局好的 GUI 程序添加各種響應(yīng)功能
個股查詢按鈕
為個股查詢的抓取按鈕綁定方法catch
self.bt?=?ttk.Button(color_group,?text='抓取',?bootstyle='success',?command=self.catch)
方法catch
的定義如下
????def?catch(self): ????????self.txt.yview_moveto(1) ????????now?=?datetime.datetime.now().strftime('%Y-%m-%d?%H:%M:%S') ????????day?=?datetime.datetime.now().strftime('%Y-%m-%d') ????????if?self.cbvar.get()?==?1: ????????????catch_day?=?self.en0.get() ????????????if?self.en.get(): ????????????????code?=?self.en.get() ????????????????result?=?catchFunc.get_A_days(code) ????????????????if?result: ????????????????????saveFunc.save_data_days(result,?catch_day) ????????????????????self.txt.insert(ttk.INSERT,?"抓取股票%s成功?%s"?%?(code,?now)) ????????????????????self.txt.insert(ttk.INSERT,?"\n") ????????????????????self.txt.update() ????????????????????self.txt.yview_moveto(1) ????????????????else: ????????????????????print("股票代碼錯誤") ????????????????????messbox.showerror("股票代碼錯誤",?"請輸入正確的股票代碼!") ????????????else: ????????????????print("請輸入股票代碼") ????????????????messbox.showerror("股票代碼為空",?"請輸入股票代碼!") ????????else: ????????...
批量查詢開關(guān)
對于批量查詢,我們是通過一個多選框開關(guān)控制的
self.cb_batch?=?ttk.Checkbutton(cr_group,?text="開啟批量",?variable=self.cbvar1,?command=self.cb_button)
綁定的方法如下
????def?cb_button(self): ????????if?self.cbvar1.get()?==?1: ????????????self.bt_batch.config(state=NORMAL) ????????else: ????????????self.bt_batch.config(state=DISABLED)
以上就是Python+Tkinter制作股票數(shù)據(jù)抓取小程序的詳細內(nèi)容,更多關(guān)于Python Tkinter股票數(shù)據(jù)抓取的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python繪圖并標(biāo)記出指定點(最大值點)方法實例
我們在用python畫散點圖的時候經(jīng)常會需要標(biāo)記出特定的點,這篇文章主要給大家介紹了關(guān)于Python繪圖并標(biāo)記出指定點(最大值點)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-05-05基于Python實現(xiàn)MUI側(cè)滑菜單a標(biāo)簽跳轉(zhuǎn)
這篇文章主要介紹了基于Python實現(xiàn)MUI側(cè)滑菜單a標(biāo)簽跳轉(zhuǎn),mui最接近原生APP體驗的高性能前端框架,MUI側(cè)滑常見的場景有下拉刷新,側(cè)滑抽屜,側(cè)滑刪除,側(cè)滑返回以及側(cè)滑菜單等等,下面來看看文章內(nèi)容詳細的介紹,需要的朋友可以參考一下2021-11-11Python使用MySQL8.2讀寫分離實現(xiàn)示例詳解
在這篇文章中,我們將了解如何將?MySQL?8.2?的讀寫分離功能與?MySQL-Connector/Python?一起使用的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11使用Anaconda3建立虛擬獨立的python2.7環(huán)境方法
今天小編就為大家分享一篇使用Anaconda3建立虛擬獨立的python2.7環(huán)境方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06Python列表list解析操作示例【整數(shù)操作、字符操作、矩陣操作】
這篇文章主要介紹了Python列表list解析操作,結(jié)合實例形式分析了Python列表針對整數(shù)、字符及矩陣的解析操作實現(xiàn)技巧,需要的朋友可以參考下2017-07-07詳解Python調(diào)用系統(tǒng)命令的六種方法
這篇文章主要介紹了詳解Python調(diào)用系統(tǒng)命令的六種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01