InsCode AI IDE工具自动生成股票行情页面
具体思路:建立一个flask项目,通过界面输入的股票代码,提交到后台以后,根据对应的股票代码去某网站爬取需要的数据,并将数据展示在index.html页面中。提示词:创建一个flask项目,判断如果前台提交方法不是post则直接返回index.html,如果提交方法是post,则接收前台提交的stockCode参数,并将取得的参数传入fetch_stock_data函数,将返回的值放入data中,
具体思路:
建立一个flask项目,通过界面输入的股票代码,提交到后台以后,根据对应的股票代码去某网站爬取需要的数据,并将数据展示在index.html页面中。
具体操作步骤如下:
- 新建一个工程
工程名称为stock如下:
- 新建一个文件夹templates,并在文件夹下新建index.html文件
目录结构如下:
- 清空main.py文件,在文件中按Ctrl+j,并输入下面的提示词,自动生成代码。
提示词:
创建一个flask项目,判断如果前台提交方法不是post则直接返回index.html,如果提交方法是post,则接收前台提交的stockCode参数,并将取得的参数传入fetch_stock_data函数,将返回的值放入data中,如果data值是None直接返回前台,并错误提示:股票代码错误,无法获取股票数据。调用process_data函数并传入data['Result']['newMarketData']['marketData'][0]['p']参数,将返回值放入processed_data中。并循环读取processed_data值,将第一个元素放入列表1中,将第二个元素放入列表2中。将1到242放入列表3中,并把data,列表1、列表2、列表3作为参数返回前台。编写一个自定义过滤器,将传入的列表进行反转并返回。编写process_data函数,传入一个参数,以;为分隔符进行分割。并循环取出子元素,对子元素以,作为分隔符。并把子元素中第一个元素以空格为分隔符后取第一个元素,子元素的第二个元素,子元素的第三个元素组成一个列表,并将该列表追加到新列表中,作为函数的返回值。建立fetch_stock_data函数传入股票代码,并用股票代码替换网址https://finance.pae.baidu.com/vapi/v1/getquotation?all=1&srcid=5353&pointType=string&group=quotation_minute_ab&market_type=ab&new_Format=1&finClientType=pc&query={stock_code}&code={stock_code}中的stock_code,并爬取该网址的内容,传入headers,如果爬取数据中Result为None,则返回None,如果有值,则返回json数据
下图是自动生成main.py与修改后的main.py文件对比。红色部分为手工修改代码。
- 打开templates/index.html文件,按ctrl+j,输入提示词
提示词:
创建一个html页面,标题名称为股票查询界面,页面背景颜色为#F3F5FA。页面布局,创建一个div名称为container,宽900高800,背景颜色#E3E7F6,居中显示边框1px红色。container内部第一行创建一个div名称为div1占满整行边框1px绿色,靠左显示,第二行创建一个div名称为div2,占满整行,边框1px紫色,靠左显示,第三行创建一个div名称div3,占满整行,边框1px黄色靠左显示。第四行创建一个div名称为div4,占满整行,边框1px蓝色。第五行创建一个div名称div5,占满整行边框1px黑色,在div5中创建div名称为div51占整行的75%边框1px粉色,在创建一个div名称div52占整行的24%边框1px橙色。在div1中创建一个form表单并以post方式提交,里面有一个标签名称为股票代码,一个文本框,一个提交按钮。在div2中使用{%if data%}判断,并使用{%if data.Result.cur.increase|float>=0 %}判断是否大于0,如果大于0则cur.avgPrice、cur.increase和cur.ratio的字体为#FF3333颜色,否则字体颜色为#0AAB62。在后面显示avgPrice(字体大小为25px)、increase和ratio,只显示值不显示标题,如果返回的error有值,则显示在container中间。在div3中判断{% if data %}如果为真,则在div3中显示data.Result.basicinfos中的显示name(字体大小为25px)、code、exchange、tradeStatus四个值显示在一行都使用span标签。在div4中判断{% if data %}是否为真,如果为真循环取出data.Result.pankouinfos.list的元素,判断loop.index-1取5的余数,如果等于0,则添加换行符。显示元素中的name,元素中的status如果值为up则value值为#FF3333,如果为down则value值为#0AAB62,否则,value颜色为黑色,并且name设置固定宽度100px边框1px颜色为红色左浮动和value设置固定宽度85px边框1px绿色左浮动,name左对齐,value右对齐。在div51中使用Chart.js将{{ list1}}设置为横坐标,将{{ list2 }}设置为第一个折线的纵坐标,折线颜色#416DF9,label名称为价格,将{{ list3 }}设置为第二个折线的纵坐标,折线颜色#FAA90E,label名称为均价,并隐藏x轴刻度数据。在div52中如果{% if data %}有值,则循环取出data.Result.askinfos元素,循环展示askprice、askvolume。循环取出data.Result.buyinfos元素使用span标签展示bidprice、bidvolume。循环取出data.Result.detailinfos元素,使用span标签展示formatTime、price、volume、bsFlag(如果bsFlag为B则颜色为#FF3333,如果为S则#0AAB62),只展示10条,并添加竖向滚动条。
自动生成的index.html与修改后的对比如下:
- 最终代码
1)、main.py
from flask import Flask, request, render_template
import requests
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
data=None
if request.method != 'POST':
return render_template('index.html',data=data)
stock_code = request.form.get('stockCode')
data = fetch_stock_data(stock_code)
if data is None:
return render_template('index.html', data=None,error="股票代码错误,无法获取股票数据")
processed_data = process_data(data['Result']['newMarketData']['marketData'][0]['p'])
list1 = []
list2 = []
for item in processed_data:
list1.append(eval(item[1]))
list2.append(eval(item[2]))
list3 = list(range(1, 243))
return render_template('index.html', data=data, list1=list1, list2=list2, list3=list3)
#自制的过滤器,用于反转字符串
def reverse_filter(s):
return s[::-1]
app.add_template_filter(reverse_filter,'lireverse')
def process_data(data):
new_list = []
sub_elements = data.split(';')
for sub in sub_elements:
items = sub.split(',')
if len(items) >= 3:
new_list.append([items[1].split(' ')[1], items[2], items[3]])
return new_list
def fetch_stock_data(stock_code):
url = f"https://finance.pae.baidu.com/vapi/v1/getquotation?all=1&srcid=5353&pointType=string&group=quotation_minute_ab&market_type=ab&new_Format=1&finClientType=pc&query={stock_code}&code={stock_code}"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'Cookie':'BIDUPSID=25A7A5A3B1146E8D3BFF1E36733F20CC; PSTM=1721007250; BAIDUID=25A7A5A3B1146E8DADC7CD866B54B1AE:FG=1; BDUSS_BFESS=Q3anVZVjNOWkN1NzR-V3RrOEtXNnlqamlTcXBrckowajIyTm52UGtEWC13NzVtRUFBQUFBJCQAAAAAAAAAAAEAAACdlpJFd2FzYWlfMTk4MjA3MjMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP42l2b-NpdmdV; H_WISE_SIDS_BFESS=60276_60359_60465_60491_60498_60551_60564; delPer=0; PSINO=2; BAIDUID_BFESS=25A7A5A3B1146E8DADC7CD866B54B1AE:FG=1; ZFY=BixeZe8xMy5mbWLmW1MB:A7BwtfD1c2hr5D:BoH9FgmXk:C; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; H_PS_PSSID=60276_60359_60564; BA_HECTOR=a02g05a4252lak812l8la10l8jr7j11jb054u1u; H_WISE_SIDS=60276_60359_60564; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; ab_sr=1.0.1_ZGNkOTE1MzQxYTM0OGZiMTI4OTcxMGUxMjNmYmM4MDE4NzBlMTI3ODJlMDdhMTA2ZmJjNDdmYWU0MmIyNWIyMmQ0ZjkwNGNkNjA4NzE5YWVjODcyYzQ4N2JlNGQ2NWMxZWZkY2U2Njc1NjdmMDRmMWUxYmJjODc4YzYwN2IyOGM5YmI1ZDBlZDQ1YjhjMTJjYTU5YWRhMjBmYjI1MzUwYg==',
}
response = requests.get(url, headers=headers)
if response.ok:
json_data = response.json()
if json_data.get('Result') is None:
return None
return json_data
return None
if __name__ == '__main__':
app.run(debug=True)
2)、templates/index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>股票查询界面</title>
<style>
body {
background-color: #F3F5FA;
}
#container {
width: 900px;
height: 800px;
background-color: #E3E7F6;
margin: 0 auto;
/*border: 1px solid red;*/
}
.row {
width: 100%;
clear: both;
}
#div1, #div2, #div3, #div4, #div5 {
width: 100%;
/*border: 1px solid;*/
}
#div1 {
/*border-color: green;*/
}
#div2 {
/* border-color: purple;*/
}
#div3 {
/* border-color: yellow;*/
}
#div4 {
/* border-color: blue;*/
}
#div5 {
/* border-color: black;*/
}
#div51 {
float: left;
width: 75%;
/* border: 1px solid pink;*/
}
#div52 {
float: left;
width: 24%;
/*border: 1px solid orange;*/
}
.pankou-info {
overflow: hidden;
margin-bottom: 10px;*/
}
.name {
float: left;
width: 110px;
/* border: 1px solid red;*/
text-align: left;
}
.value {
float: left;
width: 95px;
/* border: 1px solid green;*/
text-align: right;
}
#ask-l{
display: inline-block; /*规定长度*/
width: 30%;
text--align: left;
float:left;
}
#ask-r{
display: inline-block; /*规定长度*/
width: 20%;
text-align: right;
float:left;
}
#div521{
float: left;
width: 100%;
margin 0,auto;
/* border: 1px solid red;*/
}
#div51 span{
/* border: 1px solid orange;*/
margin-right: 250px;
}
#div77 {
width: 100%;
height: 200px;
overflow-y: scroll;
}
#de-l{
display: inline-block; /*规定长度*/
width: 25%;
text--align: left;
float:left;
}
#de-r{
display: inline-block; /*规定长度*/
width: 30%;
text-align: right;
float:left;
}
#de-rr{
display: inline-block; /*规定长度*/
width: 15%;
text-align: right;
float:left;
}
</style>
</head>
<body>
<div id="container">
<div id="div1" class="row">
<form method="post">
<label for="stockCode">股票代码:</label>
<input type="text" id="stockCode" name="stockCode">
<button type="submit">提交</button>
</form>
</div>
<div id="div2" class="row">
{% if data %}
<span style="color: {% if data.Result.cur.increase|float >= 0 %}#FF3333{% else %}#0AAB62{% endif %}; font-size: 25px;">{{ data.Result.cur.avgPrice }}</span>
<span style="color: {% if data.Result.cur.increase|float >= 0 %}#FF3333{% else %}#0AAB62{% endif %};">{{ data.Result.cur.increase }}</span>
<span style="color: {% if data.Result.cur.increase|float >= 0 %}#FF3333{% else %}#0AAB62{% endif %};">{{ data.Result.cur.ratio }}</span>
{% endif %}
{% if error %}
<div style="text-align: center;">{{ error }}</div>
{% endif %}
</div>
<div id="div3" class="row">
{% if data %}
<span style="font-size: 25px;">{{ data.Result.basicinfos.name }}</span>
<span>{{ data.Result.basicinfos.code }}</span>
<span>{{ data.Result.basicinfos.exchange }}</span>
<span>{{ data.Result.basicinfos.tradeStatus }}</span>
{% endif %}
</div>
<div id="div4" class="row">
{% if data %}
{% for info in data.Result.pankouinfos.list %}
<span class="name">{{ info.name }}</span>
<span class="value" style="color: {% if info.status == 'up' %}#FF3333{% elif info.status == 'down' %}#0AAB62{% else %}black{% endif %};">{{ info.value }}</span>
{% if loop.index % 5 == 0 %}
<br>
{% endif %}
{% endfor %}
{% endif %}
</div>
<div id="div5" class="row">
<div id="div51">
{%if data%}
<div style="text-align: center;font-size:47px;">分时折线图</div>
<canvas id="myChart"></canvas>
<span >09:30</span><span >11:30/13:00</span><span >15:00</span>
{%endif%}
</div>
<div id="div52" class="scrollable">
<div id='div521'>
{% if data %}
{% for ask in data.Result.askinfos %}
<span id='ask-l'>卖{{5-loop.index+1}} </span><span id='ask-l'> {{ask.askprice}}</span> <span id='ask-r'> {{((ask.askvolume|int) /100)|int}}</span>
{% endfor %}</div><hr>
<div id='div521'>
{% for bid in data.Result.buyinfos %}
<span id='ask-l'>买{{loop.index}}</span><span id='ask-l'> {{bid.bidprice}}</span> <span id='ask-r'> {{((bid.bidvolume|int)/100)|int}}<br></span>
{% endfor %}</div><hr>
<div id='div77'>
{% for detail in data.Result.detailinfos|lireverse %}
<span id='de-l'> {{detail.formatTime}}</span><span id='de-l'>{{detail.price}}</span><span id='de-r'>{{((detail.volume|int)/100)|int}}</span>
<span id='de-rr'>
{%if detail.bsFlag=='B' %}
<span style ="color:#FF3333">
{%elif detail.bsFlag=='S' %}
<span style ="color:#0AAB62">
{%endif%}
{{detail.bsFlag}}</span>
<br></span>
{% endfor %}
{% endif %}
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: {{ list3 }},
datasets: [{
label: '价格',
data: {{ list1 }},
borderColor: '#416DF9',
borderWidth: 1,pointRadius: 0,
fill: false
}, {
label: '均价',
data: {{ list2 }},
borderColor: '#FAA90E',
borderWidth: 1,pointRadius: 0,
fill: false
}]
},
options: {
scales: {
x: {
display: false
}
}
}
});
</script>
</body>
</html>
- 运行代码展示结果
在终端界面输入python main.py
- 展示网页
输入http://127.0.0.1:5000/展示界面如下:
更多推荐
所有评论(0)