Python实验1——网络爬虫及数据可视化
一、实验目标与基本要求
实验目标
开发网络爬虫在东方财富、新浪财经或者纳斯达克等财经网站上爬取一只股票的每天的开盘价,收盘价,最高价,最低价等信息,并存储在数据库中,并开发GUI应用可视化。
基本要求
(1) 掌握网络爬虫的开发方法;
(2) 掌握Python开发数据库的GUI界面;
(3) 掌握Matplotlib绘制股票的K线图;
二、主要知识点、重点与难点
主要知识点
(1) 网络爬虫的基本知识;
(2) 利用正则表达式对网页信息提取;
(3) 数据库的访问和表中的数据操作;
(4) Matplotlib库的使用。
重点
(1) 网络爬虫框架的使用;
(2) 正则表达式的使用;
(3) 数据库存储数据。
难点
(1) 利用正则表达式根据网页中的信息组织方式提取数据;
(2) K线图的展现。
三、实验过程设计
获取网页
def getHtml(stack_code):
data = requests.get("http://quotes.money.163.com/trade/lsjysj_" +
stack_code + ".html#06f01",
headers={"user-agent": "Mozilla/5.0"})
# 获得一个请求得到的静态网页
return data.text
爬取的网站是网易财经的股票历史交易记录。经过观察发现,不同股票历史交易记录的区别在于中间的一段股票代码,于是通过输入股票代码来获取指定股票的交易网页。
为了便于下面的数据处理,直接返回网页的text,省去了一步处理过程。(json.dumps应该也可以获取内容,作用是把str数据直接转换成字典,但是对数据有格式要求)
获取数据
json的函数dumps可以直接把网页转化成字典,但是可以自己实现的还是自己写。
def getData(data):
month_data = []
soup = BeautifulSoup(data, "html.parser")
# 爬取网页的工具
list = soup.find("div", class_="inner_box").find("table", class_="table_bg001 border_box limit_sale")
# 看html,已经把不需要的都删了,数据在innerbox的table_bg001 border_box limit_sale下面
# print(list)
dataList = list.find_all("tr")[1:]
# 因为第一个tr后面是一堆th标签,不需要
# print(dataList)
f = open("data.txt", "a+", encoding="utf-8")
for item in dataList:
kv = {}
if isinstance(item, bs4.element.Tag):
tdList = item.find_all("td")
# print(tdList)
kv["日期"] = tdList[0].text # 去掉td和/td,取中间的内容
kv["开盘价"] = tdList[1].text
kv["最高价"] = tdList[2].text
kv["最低价"] = tdList[3].text
kv["收盘价"] = tdList[4].text
kv["成交量"] = tdList[7].text
month_data.append(kv)
to_write = json.dumps(kv)
f.write(to_write)
f.close()
return month_data
首先通过BeautifulSoup得到网页格式处理的soup,通过浏览器访问防止反爬虫。
<div class="inner_box">
<div class="search_area align_r">
<form id="date" action="/trade/lsjysj_300153.html">
<select name="year">
<option value="2021" selected>2021</option><option value="2020" >2020</option><option value="2019" >2019</option><option value="2018" >2018</option><option value="2017" >2017</option><option value="2016" >2016</option><option value="2015" >2015</option><option value="2014" >2014</option><option value="2013" >2013</option><option value="2012" >2012</option><option value="2011" >2011</option><option value="2010" >2010</option> </select>
<select name="season">
<option value="4" >四季度</option><option value="3" >三季度</option><option value="2" selected>二季度</option><option value="1" >一季度</option> </select>
<input type="submit" value="查询" class="search_btn"/>
<a href="" class="download_link" id="downloadData">下载数据</a>
</form>
</div>
<table class="table_bg001 border_box limit_sale">
<thead>
<tr class="dbrow">
<th>日期</th>
<th>开盘价</th>
<th>最高价</th>
<th>最低价</th>
<th>收盘价</th>
<th>涨跌额</th>
<th>涨跌幅(%)</th>
<th>成交量(手)</th>
<th>成交金额(万元)</th>
<th>振幅(%)</th>
<th>换手率(%)</th>
</tr>
</thead>
<tr class=''>
<td>2021-05-14</td>
<td class='cRed'>6.94</td>
<td class='cRed'>8.10</td>
<td class='cRed'>6.78</td>
<td class='cRed'>8.10</td>
<td class='cRed'>1.35</td>
<td class='cRed'>20.00</td>
<td>489,575</td>
<td>36,666</td>
<td>19.56</td>
<td>15.30</td>
</tr>
<tr class='dbrow'>
<td>2021-05-13</td><td class='cGreen'>7.03</td><td class='cRed'>7.18</td><td class='cGreen'>6.74</td><td class='cGreen'>6.75</td><td class='cGreen'>-0.28</td><td class='cGreen'>-3.98</td><td>291,380</td><td>20,160</td><td>6.26</td><td>9.11</td></tr><tr class=''><td>2021-05-12</td><td class='cGreen'>6.40</td><td class='cRed'>7.36</td><td class='cGreen'>6.26</td><td class='cRed'>7.03</td><td class='cRed'>0.54</td><td class='cRed'>8.32</td><td>429,979</td><td>30,069</td><td>16.95</td><td>13.44</td></tr><tr class='dbrow'><td>2021-05-11</td><td class='cGreen'>6.53</td><td class='cGreen'>6.58</td><td class='cGreen'>6.25</td><td class='cGreen'>6.49</td><td class='cGreen'>-0.15</td><td class='cGreen'>-2.26</td><td>207,696</td><td>13,307</td><td>4.97</td><td>6.49</td></tr><tr class=''><td>2021-05-10</td><td class='cGreen'>6.58</td><td class='cRed'>7.06</td><td class='cGreen'>6.48</td><td class='cGreen'>6.64</td><td class='cGreen'>-0.12</td><td class='cGreen'>-1.78</td><td>275,209</td><td>18,406</td><td>8.58</td><td>8.60</td></tr><tr class='dbrow'><td>2021-05-07</td><td class='cRed'>7.10</td><td class='cRed'>7.15</td><td class='cGreen'>6.56</td><td class='cGreen'>6.76</td><td class='cGreen'>-0.25</td><td class='cGreen'>-3.57</td><td>319,005</td><td>21,693</td><td>8.42</td><td>9.97</td></tr><tr class=''><td>2021-05-06</td><td class='cRed'>6.73</td><td class='cRed'>7.35</td><td class='cGreen'>6.60</td><td class='cRed'>7.01</td><td class='cRed'>0.41</td><td class='cRed'>6.21</td><td>426,529</td><td>29,506</td><td>11.36</td><td>13.33</td></tr><tr class='dbrow'><td>2021-04-30</td><td class='cRed'>6.97</td><td class='cRed'>7.30</td><td class='cGreen'>6.27</td><td class='cGreen'>6.60</td><td class='cGreen'>-0.06</td><td class='cGreen'>-0.90</td><td>529,436</td><td>35,333</td><td>15.47</td><td>16.54</td></tr><tr class=''><td>2021-04-29</td><td class='cGreen'>5.50</td><td class='cRed'>6.66</td><td class='cGreen'>5.41</td><td class='cRed'>6.66</td><td class='cRed'>1.11</td><td class='cRed'>20.00</td><td>382,602</td><td>23,741</td><td>22.52</td><td>11.96</td></tr><tr class='dbrow'><td>2021-04-28</td><td class='cGreen'>5.64</td><td class='cRed'>5.86</td><td class='cGreen'>5.53</td><td class='cGreen'>5.55</td><td class='cGreen'>-0.27</td><td class='cGreen'>-4.64</td><td>196,804</td><td>11,068</td><td>5.67</td><td>6.15</td></tr><tr class=''><td>2021-04-27</td><td class='cGreen'>6.06</td><td class='cGreen'>6.14</td><td class='cGreen'>5.65</td><td class='cGreen'>5.82</td><td class='cGreen'>-0.44</td><td class='cGreen'>-7.03</td><td>286,392</td><td>16,754</td><td>7.83</td><td>8.95</td></tr><tr class='dbrow'><td>2021-04-26</td><td class='cGreen'>6.28</td><td class='cGreen'>6.48</td><td class='cGreen'>5.89</td><td class='cGreen'>6.26</td><td class='cGreen'>-0.39</td><td class='cGreen'>-5.86</td><td>397,512</td><td>24,395</td><td>8.87</td><td>12.42</td></tr><tr class=''><td>2021-04-23</td><td class='cRed'>6.38</td><td class='cRed'>7.20</td><td class='cRed'>6.18</td><td class='cRed'>6.65</td><td class='cRed'>0.60</td><td class='cRed'>9.92</td><td>593,691</td><td>40,159</td><td>16.86</td><td>18.55</td></tr><tr class='dbrow'><td>2021-04-22</td><td class='cGreen'>5.03</td><td class='cRed'>6.05</td><td class='cGreen'>5.03</td><td class='cRed'>6.05</td><td class='cRed'>1.01</td><td class='cRed'>20.04</td><td>349,405</td><td>19,949</td><td>20.24</td><td>10.92</td></tr><tr class=''><td>2021-04-21</td><td class='cRed'>5.15</td><td class='cRed'>5.15</td><td class='cGreen'>5.03</td><td class='cGreen'>5.04</td><td class='cGreen'>-0.08</td><td class='cGreen'>-1.56</td><td>28,485</td><td>1,444</td><td>2.34</td><td>0.89</td></tr><tr class='dbrow'><td>2021-04-20</td><td class='cGreen'>5.17</td><td class='cRed'>5.24</td><td class='cGreen'>5.12</td><td class='cGreen'>5.12</td><td class='cGreen'>-0.07</td><td class='cGreen'>-1.35</td><td>38,135</td><td>1,976</td><td>2.31</td><td>1.19</td></tr><tr class=''><td>2021-04-19</td><td class='cGreen'>5.15</td><td class='cRed'>5.25</td><td class='cGreen'>5.12</td><td class='cRed'>5.19</td><td class='cRed'>0.03</td><td class='cRed'>0.58</td><td>41,940</td><td>2,178</td><td>2.52</td><td>1.31</td></tr><tr class='dbrow'><td>2021-04-16</td><td class='cGreen'>4.97</td><td class='cRed'>5.19</td><td class='cGreen'>4.95</td><td class='cRed'>5.16</td><td class='cRed'>0.19</td><td class='cRed'>3.82</td><td>42,536</td><td>2,172</td><td>4.83</td><td>1.33</td></tr><tr class=''><td>2021-04-15</td><td class='cGreen'>5.04</td><td class='cGreen'>5.05</td><td class='cGreen'>4.94</td><td class='cGreen'>4.97</td><td class='cGreen'>-0.10</td><td class='cGreen'>-1.97</td><td>30,343</td><td>1,514</td><td>2.17</td><td>0.95</td></tr><tr class='dbrow'><td>2021-04-14</td><td class='cRed'>4.91</td><td class='cRed'>5.08</td><td class='cGreen'>4.87</td><td class='cRed'>5.07</td><td class='cRed'>0.18</td><td class='cRed'>3.68</td><td>31,385</td><td>1,559</td><td>4.29</td><td>0.98</td></tr><tr class=''><td>2021-04-13</td><td class='cRed'>5.04</td><td class='cRed'>5.05</td><td class='cGreen'>4.82</td><td class='cGreen'>4.89</td><td class='cGreen'>-0.11</td><td class='cGreen'>-2.20</td><td>34,050</td><td>1,669</td><td>4.60</td><td>1.06</td></tr><tr class='dbrow'><td>2021-04-12</td><td class='cGreen'>5.09</td><td class='cGreen'>5.12</td><td class='cGreen'>4.98</td><td class='cGreen'>5.00</td><td class='cGreen'>-0.12</td><td class='cGreen'>-2.34</td><td>37,899</td><td>1,901</td><td>2.73</td><td>1.18</td></tr><tr class=''><td>2021-04-09</td><td class='cRed'>5.15</td><td class='cRed'>5.24</td><td class='cRed'>5.11</td><td class='cRed'>5.12</td><td class='cRed'>0.05</td><td class='cRed'>0.99</td><td>47,592</td><td>2,458</td><td>2.56</td><td>1.49</td></tr><tr class='dbrow'><td>2021-04-08</td><td class='cRed'>5.29</td><td class='cRed'>5.29</td><td class='cGreen'>5.07</td><td class='cGreen'>5.07</td><td class='cGreen'>-0.18</td><td class='cGreen'>-3.43</td><td>54,769</td><td>2,815</td><td>4.19</td><td>1.71</td></tr><tr class=''><td>2021-04-07</td><td class='cGreen'>5.21</td><td class='cRed'>5.28</td><td class='cGreen'>5.19</td><td class='cRed'>5.25</td><td class='cRed'>0.04</td><td class='cRed'>0.77</td><td>31,196</td><td>1,632</td><td>1.73</td><td>0.97</td></tr><tr class='dbrow'><td>2021-04-06</td><td class='cRed'>5.19</td><td class='cRed'>5.26</td><td class='cGreen'>5.13</td><td class='cRed'>5.21</td><td class='cRed'>0.04</td><td class='cRed'>0.77</td><td>38,493</td><td>2,005</td><td>2.51</td><td>1.20</td></tr><tr class=''><td>2021-04-02</td><td class='cGreen'>5.06</td><td class='cRed'>5.18</td><td class='cGreen'>5.06</td><td class='cRed'>5.17</td><td class='cRed'>0.04</td><td class='cRed'>0.78</td><td>43,675</td><td>2,231</td><td>2.34</td><td>1.36</td></tr><tr class='dbrow'><td>2021-04-01</td><td class='cRed'>5.30</td><td class='cRed'>5.34</td><td class='cGreen'>5.05</td><td class='cGreen'>5.13</td><td class='cGreen'>-0.13</td><td class='cGreen'>-2.47</td><td>57,846</td><td>2,967</td><td>5.51</td><td>1.81</td></tr></tr> </table>
</div>
通过查看网页源码,找到数据所在的标签是:名字为inner_box的div下的,名字为table_bg001 border_box limit_sale的table下的,每一个tr标签中的内容。这就可以通过soup的find方法找到数据了
list = soup.find("div", class_="inner_box").
find("table", class_="table_bg001 border_box limit_sale")
list中存放的就是一堆tr标签,仍然保留html的格式。
dataList = list.find_all("tr")[1:]
因为table下的第一项是一系列的th标签,没有数据,所以去掉这一项。
<td>2021-05-14</td>
<td class='cRed'>6.94</td>
<td class='cRed'>8.10</td>
<td class='cRed'>6.78</td>
<td class='cRed'>8.10</td>
<td class='cRed'>1.35</td>
<td class='cRed'>20.00</td>
<td>489,575</td>
<td>36,666</td>
<td>19.56</td>
<td>15.30</td>
再看一下每一天数据的格式。
f = open("data.txt", "a+", encoding="utf-8")
for item in dataList:
kv = {}
if isinstance(item, bs4.element.Tag):
tdList = item.find_all("td")
# print(tdList)
kv["日期"] = tdList[0].text # 去掉td和/td,取中间的内容
kv["开盘价"] = tdList[1].text
kv["最高价"] = tdList[2].text
kv["最低价"] = tdList[3].text
kv["收盘价"] = tdList[4].text
kv["成交量"] = tdList[7].text
month_data.append(kv)
to_write = json.dumps(kv)
f.write(to_write)
f.close()
把每一天的数据保存成一个字典,把一只股票的数据保存到一个列表中。tdlist存放了一天数据,通过下标找到对应的列数据,同时去掉标签tr,并保存到txt中。
保存到数据库
def Storage(data):
my_database = mysql.connector.connect(
host="localhost",
user="root",
passwd="123456",
auth_plugin='mysql_native_password'
)
cursor = my_database.cursor()
sql_createDataBase = "create database if not exists stockData"
cursor.execute(sql_createDataBase)
sql_useDataBase = "USE stockData"
cursor.execute(sql_useDataBase)
sql_createTable = '''create table if not exists data(
date DATE,/
opening_price float,
closing_price float,
highest float,
lowest float)
'''
cursor.execute(sql_createTable)
for item in data:
sql_Insert = '''Insert into data values
('{0}',{1},{2},{3},{4})'''.format(item['日期'], item['开盘价'], item['收盘价'], item['最高价'], item['最低价'])
cursor.execute(sql_Insert)
cursor.close()
my_database.commit()
my_database.close()
print(my_database)
首先建立数据库连接,创建新的数据库和股票数据表,列名为爬取的数据内容。将之前的数据插入数据库,然后关闭数据库连接。注意在python中执行sql语句需要通过由标的execute函数执行,对于插入,运用了字符串的format函数,预留出每一个值,填入数组的对应位置。
数据预处理
因为画K线图函数需要用到元组形式的数据,这里做一个数据处理
def data_Pretreatment(month_data, date, opening_price, closing_price, highest, lowest):
for data in month_data:
my_date = data.get("日期")
my_open = data.get("开盘价")
my_close = data.get("收盘价")
my_high = data.get("最高价")
my_low = data.get("最低价")
date.append(my_date)
opening_price.append(my_open)
closing_price.append(my_close)
highest.append(my_high)
lowest.append(my_low)
遍历预处理之后的数据,整理成新的列表。
绘制独立数据图像
def draw(month_data,lowest):
bar1 = Bar()
bar1.add_xaxis(date)
bar1.add_yaxis("最低价", lowest)
bar1.set_series_opts(
# 是否显示标签
label_opts=opts.LabelOpts(is_show=False)
, markpoint_opts=opts.MarkPointOpts(
data=[opts.MarkPointItem(type_="max", name="max"),
opts.MarkPointItem(name="min", type_="min")]
),
markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(name="average", type_="average")]))
bar1.set_global_opts(
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(rotate=-60, font_size=10),
),
yaxis_opts=opts.AxisOpts(
name="价格:(元/股)",
),
)
bar1.render("最低价.html")
这里用到了一个交互性的库pyecharts,可以把数据保存为静态html,而且可以与用户交互。注意到数据有三十个,一页是放不下的,因此设置数据的横坐标倾斜角度为60,保证能够在一页内显示所有数据。
绘制K线图
def draw_K(opening_price, closing_price, lowest, highest):
kline = Kline("K线图")
v1 = []
size = len(opening_price)
for i in range(0, size):
tmp = [opening_price[i], closing_price[i], lowest[i], highest[i]]
v1.append(tmp)
print(v1)
kline.add("日K",
["2021/4/{}".format(i + 1) for i in range(30)],
v1,
mark_point=["max", "min"],
is_datazoom_show=True,
datazoom_orient="horizontal",
mark_line_valuedim="close",
)
kline.render("K图.html")
通过处理之后的数据,很方便的作为画图函数的4个参数传入,这里同样有数据太多无法显示的问题,因为K线图细节很多,无法缩小,因此设置水平方向的滚动条,可以看到完整的数据图像。
数据转化、存储为Excel
这也是数据处理,一方面GUI可以显示Excel表格,另一方面下一张股票分析图需要DataFrame类型的股票数据,在这个函数里实现这两个功能。
def store_in_dataframe(month_data):
my_list = []
for item in month_data:
tmp = list(item.values())
my_list.append(tmp)
# print(my_list)
my_dataframe = pd.DataFrame(my_list,
columns=["datetime", 'open', 'close', 'low', 'high', "trade_sum"])
print(my_dataframe)
my_dataframe.to_excel("数据.xlsx")
return my_dataframe
绘制股票信息分析图
这是结合K线图对股票信息进行进一步分析,结合pyecharts,可以做到:
1.在一张图上显示多条曲线(Overlap的功能),用户可以自行选择隐藏不需要的曲线。
2.在K线图下方显示股票当天成交量的柱状图。
3.提示用户股票buy和sell的点供参考。
def back_testing_plot(table_name, indicator_name_list):
# data preparation
da = pd.DataFrame(data=table_name)
# da['trade_sum'] = da['trade_sum'].apply(lambda vol: vol if vol > 0 else 0)
date = da["datetime"].apply(lambda x: str(x)).tolist()
k_plot_value = da.apply(lambda record: [record['open'],
record['close'],
record['low'],
record['high']],
axis=1).tolist()
# K chart
kline = Kline()
kline.add("Back_testing Result", date, k_plot_value)
indicator_lines = Line()
for indicator_name in indicator_name_list:
indicator_lines.add(indicator_name,
date,
da[indicator_name].tolist(),
mark_point=["max", "min"],
)
# trading volume bar chart
bar = Bar()
print(type(max(da["trade_sum"])))
bar.add("trade_sum", date, da["trade_sum"],
tooltip_tragger="axis",
is_legend_show=False,
is_yaxis_show=False,
yaxis_max=5 * max(da["trade_sum"]),
)
# buy and sell
v1 = date[10]
v2 = da['high'].iloc[10]
es = EffectScatter("buy")
es.add("buy", [v1], [v2])
v1 = date[18]
v2 = da['high'].iloc[18]
es.add("sell", [v1], [v2], symbol="pin", )
overlap = Overlap()
overlap.add(kline)
overlap.add(indicator_lines, )
overlap.add(bar)
overlap.add(es)
overlap.render(path='高级图.html')
数据可视化
class MyFrame(wx.Frame):
data = []
column_names = []
stack_Code = 0
def __init__(self, data, column_names):
super().__init__(parent=None, title="股票数据显示界面", size=(600, 600))
self.data = data
self.column_names = column_names
self.Centre()
panel = wx.Panel(parent=self)
# self.message1 = wx.StaticText()
# self.message1.SetLabelText("请输入股票代码")
# self.message1.SetPosition((400,370))
self.number = wx.TextCtrl(panel, pos=(450, 370))
# query_button = wx.Button(parent=panel, id=1, label='查询', pos=(450, 400))
post = wx.Button(parent=panel, id=2, label='更新', pos=(450, 435))
show = wx.Button(parent=panel, id=3, label='查看表格', pos=(450, 470))
# self.Bind(wx.EVT_BUTTON, self.on_click, query_button)
self.Bind(wx.EVT_BUTTON, self.on_click, post)
self.Bind(wx.EVT_BUTTON, self.on_click, show)
# self.Bind(wx.EVT_TEXT, self.EvtText)
# 建立表格
def generate_xlsx(self):
self.grid = self.CreateGrid(self)
self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick)
def on_click(self, event):
event_id = event.GetId()
print(event_id)
if event_id == 1:
print("查询K图")
elif event_id == 2:
self.stack_Code = self.number.GetValue()
print(self.number.GetValue())
update_xlsx(self, self.stack_Code)
elif event_id == 3:
self.generate_xlsx()
def OnLabelLeftClick(self, event):
print("RowIdx:{0}".format(event.GetRow()))
print("ColIdx:{0}".format(event.GetCol()))
print(self.data[event.GetRow()])
event.Skip()
def CreateGrid(self, parent):
grid = wx.grid.Grid(parent)
grid.CreateGrid(len(self.data), len(self.data[0]))
for row in range(len(self.data)):
for col in range(len(self.data[row])):
grid.SetColLabelValue(col, self.column_names[col])
grid.SetCellValue(row, col, self.data[row][col])
# 设置行和列自定调整
grid.AutoSize()
return grid
class App(wx.App):
data = []
column_names = []
def show(self):
frame = MyFrame(self.data, self.column_names)
frame.Show()
return True
def update_xlsx(app, stack_code):
newData = getHtml(stack_code)
month_data = getData(newData)
my_list = []
for item in month_data:
tmp = list(item.values())
my_list.append(tmp)
app.data = my_list
def update(month_data, date, opening_price, closing_price, highest, lowest):
data_Pretreatment(month_data, date, opening_price, closing_price, highest, lowest)
draw_K(opening_price, closing_price, lowest, highest)
my_dataframe = store_in_dataframe(month_data)
back_testing_plot(my_dataframe, my_dataframe)
细节:
向界面的panel添加两个按钮,同时指定on-click函数和update函数,将按钮和函数绑定,当监听到指定id的按钮被按下,就执行相应的更新函数,绘制新的K图和表格。
功能:
界面有一个输入框和两个按钮,用户可以直接在界面上看到股票的Excel数据,也可以通过保存在file目录下的静态网页查看之前绘制的任何一张图标。
当用户输入新的股票代号并点击更新时,首先会重新爬取股票数据,同时更新Excel表格中的数据和K线图、股票数据分析图中的数据。
主函数
def main():
htmlText = getHtml(str(600975))
month_data = getData(htmlText)
month_data.sort(key=lambda k: k['日期'])
month_data.sort(key=lambda x: pd.datetime.strptime("x['日期']", '%d/%m/%Y'))
print(month_data)
Storage(month_data)
date = []
opening_price = []
closing_price = []
highest = []
lowest = []
draw(month_data, date, opening_price, closing_price, highest, lowest)
app = App()
my_list = []
for item in month_data:
tmp = list(item.values())
my_list.append(tmp)
app.data = my_list
app.column_names = ["datetime", 'open', 'close', 'low', 'high', "trade_sum"]
print(app.data)
app.show()
app.MainLoop()
if __name__ == '__main__':
main()
运行结果
默认显示国家电力的数据
输入新的股票代码,更新表格中的数据,同时更新K线图。
三组不同的数据
遇到的问题
没有能够把K线图嵌入到界面中,观察不够方便。
实验的收获
1.学会了基本的html知识,懂得利用浏览器开发者工具获取需要的网络数据。
2.实践了在高级语言中进行sql语句的嵌入执行。
3.理解了Dataframe数据格式在库函数调用中的广泛运用,熟练掌握了数据预处理和格式转换。
4.面对数据无法全部显示的时候,能根据用户对数据的需求和数据的特性,修改数据的显示特征(压缩和滚动显示)。
5.实现前台界面和后台数据的交互,保证数据的实时更新。