待业,在家无聊,想着昨天的js书签应用其实挺适合公司内部使用的,所以自己想了一个需求
业务员小王每天要出一份销售的报表,有柱状图啥的那种,他想让技术部小张帮他弄一个自动生成报表的程序,但是公司的业务系统是别家公司做的,数据也托管在那边,小张无法直接从数据库拿数据,于是他用迂回的方式,爬虫,为了方便小王使用,小张决定用js书签形式
以下是程序demo
目录:
app
|----templates
|----index.html(生成报表页面)
|----test.js(js爬虫)
|----test.py(flask程序)
先制作一个js书签,制作过程请看我上一篇博客
代码如下:
javascript:void((function(){
//创建一个元素
var e=document.createElement('script');
var ex=document.createElement('script');
//给元素添加属性
e.setAttribute('src','http://127.0.0.1:5000');
ex.setAttribute('src','http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js');
//将元素添加到页面
document.body.appendChild(e);
document.body.appendChild(ex);
})())
javascript:void((function(){var e=document.createElement('script');var ex=document.createElement('script');e.setAttribute('src','http://127.0.0.1:5000');ex.setAttribute('src','http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js');document.body.appendChild(e);document.body.appendChild(ex);})())
需要删掉注释,所以我贴了格式化的和一整行的两段代码
test.js代码:
(function(){
// 测试用
alert("js书签有效");
//需要发送的数据
var jsondata = {}
var xx = []
// var yy = []
var sulex = document.getElementsByClassName("hotArticle-list sort-list ClassSort-list");
var ex = sulex[0].getElementsByClassName("odd-overhidden floatL");
for (var i = 0; i < ex.length; i++) {
xx.push({"name":ex[i].innerText,"num":sulex[0].getElementsByClassName("read list-left floatR")[i].innerText.replace("篇","")})
}
// var dulex = document.getElementsByClassName("hotArticle-list timeSort-list");
// var eex = dulex[0].getElementsByClassName("odd-overhidden floatL");
// for (var i = 0; i < eex.length; i++) {
alert(eex[i].innerText);
alert(dulex[0].getElementsByClassName("read list-left floatR")[i].innerText);
// yy.push({"name":eex[i].innerText,"num":dulex[0].getElementsByClassName("read list-left floatR")[i].innerText.replace("篇","")})
// }
jsondata["xx"]=xx;
// jsondata["yy"]=yy;
console.log(JSON.stringify(jsondata));
$.ajax({
url:'http://127.0.0.1:5000/postdata',
type:'post', //数据发送方式
dataType:'json', //接受数据格式 (这里有很多,常用的有html,xml,js,json)
data:{"data":JSON.stringify(jsondata)}, //要传递的数据
error: function(){ //失败
alert('发送失败');
},
success: function(msg){ //成功
if(msg){
window.open(msg["url"]);
}
}
});
})();
test.py代码:
# -*-coding:utf-8 -*-
__author__ = "ZJL"
from flask import Flask
from flask import request
from flask import Response
from flask import render_template
from queue import Queue
import json
app = Flask(__name__)
#队列
q = Queue()
#跨域
def Response_headers(content):
resp = Response(content)
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
# js代码
@app.route("/")
def index():
of = open("test.js","r")
jsd = of.read()
return jsd
# js爬取的数据发送过来
@app.route("/postdata",methods=['POST'])
def postdata():
datax = request.form.to_dict()
#这里可以加一个处理的主函数,处理完成后把数据放进队列
q.put(datax["data"])
data_url = {"url":"http://127.0.0.1:5000/xxx"}
return Response_headers(json.dumps(data_url))
#展示页面
@app.route('/xxx')
def xxx ():
return render_template("index.html")
#展示页面数据
@app.route('/echarts')
def echarts():
while not q.empty():
# 队列中取出数据
x = q.get()
# print("xxxxxx",x)
resp = Response_headers(x)
return resp
if __name__ == "__main__":
app.run(debug=True)
templates/index.html 代码:
<html>
<head>
<!-- 引入 echarts.js -->
<script type="text/javascript" src="http://echarts.baidu.com/dist/echarts.js"></script>
<!-- 引入jquery.js -->
<script type="text/javascript" src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 900px;height:500px;"></div>
</body>
<script type="text/javascript">
var a = echarts;
var myChart = a.init(document.getElementById('main'));
// 显示标题,图例和空的坐标轴
myChart.setOption({
title: {
text: '数据图'
},
tooltip : {
trigger: 'axis'
},
legend: {
data:['今日数据']
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {show: true, type: ['line', 'bar']},
// restore : {show: true},
// saveAsImage : {show: true}
}
},
calculable : true,
xAxis : [
{
type : 'category',
boundaryGap : false,
data : []
}
],
yAxis : [
{
type : 'value',
axisLabel : {
formatter: '{value}'
}
}
],
series : [
{
name:'最多数量',
type:'line',
data:[],
markPoint : {
data : [
{type : 'max', name: '最大值'},
{type : 'min', name: '最小值'}
]
},
markLine : {
data : [
{type : 'average', name: '平均值'}
]
}
},]
});
myChart.showLoading(); //数据加载完之前先显示一段简单的loading动画
var names=[]; //名称数组(实际用来盛放X轴坐标值)
var nums=[]; //数量数组(实际用来盛放Y坐标值)
$.ajax({
type : "get",
// async : true, //异步请求(同步请求将会锁住浏览器,用户其他操作必须等待请求完成才可以执行)
url : "http://127.0.0.1:5000/echarts", //请求发送到Servlet处
// data : {},
dataType : "json", //返回数据形式为json
success : function(result) {
//请求成功时执行该函数内容,result即为服务器返回的json对象
if (result) {
console.log(result["xx"]);
// alert(result["xx"]);
for(var i=0;i<result["xx"].length;i++){
// alert(result["xx"][i]["name"]);
names.push(result["xx"][i]["name"]); //挨个取出名称并填入类别数组
}
for(var i=0;i<result["xx"].length;i++){
// // alert(result["xx"][i]["num"]);
nums.push(result["xx"][i]["num"]); //挨个取出数量并填入销量数组
}
myChart.hideLoading(); //隐藏加载动画
myChart.setOption({ //加载数据图表
xAxis: {
data: names
},
series: [{
// 根据名字对应到相应的系列
name: '数量',
data: nums
}]
});
}
},
error : function(errorMsg) {
//请求失败时执行该函数
alert("图表请求数据失败!");
myChart.hideLoading();
}
})
</script>
</html>
效果:
现在小王只需浏览器访问到数据页面,点击js书签,就会直接跳转到报表页面,然后只需用浏览器自带的打印功能打印出来,或者保存为pdf,就可以了,鼓掌......
如果没有跳转页面请看浏览器地址栏右边是不是拦截了弹窗
流程:
先从浏览器抓取数据,通过ajax发送给后台服务,后台接收以后处理(可以做很多处理,不光只是展示数据,还有很多统计,销量预测,销售建议等等),然后将数据发给html页面,用ECharts展示(ECharts也有很多其它的图形)