Python实验1——网络爬虫及数据可视化

一、实验目标与基本要求

实验目标

        开发网络爬虫在东方财富、新浪财经或者纳斯达克等财经网站上爬取一只股票的每天的开盘价,收盘价,最高价,最低价等信息,并存储在数据库中,并开发GUI应用可视化。

基本要求

(1) 掌握网络爬虫的开发方法;
(2) 掌握Python开发数据库的GUI界面;
(3) 掌握Matplotlib绘制股票的K线图;

二、主要知识点、重点与难点

主要知识点

(1) 网络爬虫的基本知识;
(2) 利用正则表达式对网页信息提取;
(3) 数据库的访问和表中的数据操作;
(4) Matplotlib库的使用。

重点

(1) 网络爬虫框架的使用;
(2) 正则表达式的使用;
(3) 数据库存储数据。

难点

(1) 利用正则表达式根据网页中的信息组织方式提取数据;
(2) K线图的展现。

三、实验过程设计

获取网页a
获取原始数据
保存到数据库
数据预处理
绘制独立数据图像
绘制K线图
数据转化,存储为Excel
绘制股票信息分析图
数据可视化

获取网页

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>
			&nbsp;&nbsp;
            <select name="season">
				<option value="4" >四季度</option><option value="3" >三季度</option><option value="2" selected>二季度</option><option value="1" >一季度</option>            </select>
			&nbsp;&nbsp;
            <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.实现前台界面和后台数据的交互,保证数据的实时更新。

  • 22
    点赞
  • 151
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星辰的野望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值