手动反爬虫,禁止转载: 原博地址 https://blog.csdn.net/lys_828/article/details/121287432(CSDN博主:Be_melting)
知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息
6 数据结果图形可视化
按照数据分析的金字塔,最底层的数据记录:包含收集(储存)与展示和信息传递在第5部分已经完结,接下来到大金字塔的倒数第二层,也就是对数据进行图表的输出展示,需要对数据进行整理,聚合和可视化。
6.1 航班数据的时令特征
- 在收集了航班数据之后,我们从一个问题展开,来探讨下一年中那个月飞机出现最为繁忙。
- 当一个计量值随着时间不断的循环,时令性就诞生了,比如过节,开学,放假等等。
首先进行准备工作,创建step2文件夹,并添加example01.py文件,执行如下代码。(这些代码前面部分都已经讲解过,可以形成一个框架,在read.parquet(‘某文件’)填写自己要读取的文件,然后再三引号之间填写自己要进行的查询操作即可)
from SparkReady import start_spark
spark = start_spark('C04S01',12,'8g')
on_time_dataframe = spark.read.parquet('../data/on_time.parquet')
on_time_dataframe.registerTempTable("on_time_dataframe")
total_flights_by_month = spark.sql ("""
select cast(Month as int) , cast(Year as int) , count(*) as total_flights from on_time_dataframe
group by Year, Month order by Year, cast(Month as int)
""")
total_flights_by_month.show()
由于已经按照数值的顺序进行排列,所以输出的结果如下。
结果出来之后需要将数据保存,直接转化为字典的数据类型后存放到Mongo DB中,代码操作如下。
flights_chart_data = total_flights_by_month.rdd.map(lambda x : x.asDict())
import pymongo_spark
pymongo_spark.activate()
flights_chart_data.saveToMongoDB('mongodb://localhost:27017/example.flights_by_month')
程序正常运行后,刷新Compass软件界面,就会在example数据库下面多了一个flights_by_month的数据表,如下。
6.2 利用Flask进行数据展示
将step1中wen文件夹下包含statics和templates整个文件夹直接复制到step2中,创建6.0版本的on_time06.py文件,在最后一个函数后面添加如下内容。
@app.route("/total_flights")
def total_flights():
total_flights = client.example.flights_by_month.find({},
sort=[
('Year', 1),
('Month', 1)
])
return render_template('total_flights.html',total_flights=total_flights)
由于指定了渲染的文件,所以需要在templates文件夹中添加这文件,文件中的代码内容如下。
{% extends "index.html" %}
{% block body2 %}
<div>
<p class="lead">每月飞行航班次数</p>
<table class="table table-condensed table-striped" style="width: 200px;">
<thead>
<th>月份</th>
<th>总航班数</th>
</thead>
<tbody>
{% for month in total_flights %}
<tr>
<td>{{month.Month}}</td>
<td>{{month.total_flights}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
两个文件操作完成后进行保存后运行on_time06.py,打开浏览器输入:http://127.0.0.1:5000/total_flights,输出结果内容如下。
6.3 创建接口数据
想要进行绘制图形,需要提供一个接口数据,为图形提供基础的数据来源。在进行爬虫过程中也是经常遇到接口数据,此类数据都是以json数据类型进行返回,添加的代码如下。
@app.route("/total_flights.json")
def total_flights_json():
total_flights = client.example.flights_by_month.find({},
sort=[
('Year', 1),
('Month', 1)
])
return json_util.dumps(total_flights,ensure_ascii = False)
此时再重新运行on_time_06.py后,输入:http://127.0.0.1:5000/total_flights.json,输出的结果如下。
6.4 创建可视化图形
接口数据准备完成后,就可以开始绘制图形,需要添加的代码如下。
@app.route("/total_flights_chart")
def total_flights_chart():
total_flights = client.example.flights_by_month.find({},
sort=[
('Year', 1),
('Month', 1)
])
return render_template('total_flights_chart.html', total_flights=total_flights)
这里指定了total_flights_chart.html渲染文件,就需要配置里面的内容,具体代码如下。
{% extends "index.html" %}
{% block body2 %}
<style>
.chart rect {
fill: steelblue;
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<div>
<p class="lead">每月飞行航班总数</p>
<div id="chart"><svg class="chart"></svg></div>
</div>
<script src="/static/app.js"></script>
{% endblock %}
而最终的绘图参数的相关设置,被放置在了static/app.js文件中,该文件中的全部代码如下。
var width = 960,
height = 350;
var y = d3.scale.linear()
.range([height, 0]);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", height);
d3.json("/total_flights.json", function(data) {
var barColor = 'steelblue';
var maxY = d3.max(data, function(d) { return d.total_flights; });
y.domain([0, maxY]);
var varColor = function(d, i) {
if(d['total_flights'] == maxY) { return modeColor; }
else { return defaultColor; }
}
var barWidth = width / data.length;
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
bar.append("rect")
.attr("y", function(d) { return y(d.total_flights); })
.attr("height", function(d) { return height - y(d.total_flights); })
.attr("width", barWidth - 1)
.style("fill", barColor);
bar.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.total_flights) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.total_flights; });
});
三个文件处理完毕后,进行保存后运行on_time06.py文件,浏览器的网页地址栏输入:http://127.0.0.1:5000/total_flights_chart,输出结果如下。
如果此时页面没有加载出图形,打开调试窗口会发现D3相关的配置文件没有设置好,就需要把所需要的三个文件放置在static文件夹下,并在index.html文件中进行添加代码说明,具体的代码操作结果截图如下。
可以更进一步优化内容显示,比如突出展现航班数量最多的月份,进行不同颜色的区分,on_time06.py中的函数代码基本一致,只是函数的名称和对应的渲染文件不同,代码如下。
@app.route("/total_flights_chart_2")
def total_flights_chart_2():
total_flights = client.example.flights_by_month.find({},
sort=[
('Year', 1),
('Month', 1)
])
return render_template('total_flights_chart_2.html', total_flights=total_flights)
而接下来就是对应total_flights_chart_2.html渲染文件和app.js2文件,因为和前面的代码有大量的重复,这里可以查看一下两个文件中不同的地方即可,在pycahrm中按住Ctrl键选择要对比的文件,然后鼠标右键选择Compare file选项,输出结果如下。(上面的是两个html文件的差异性对比,共有一处不同,下面的是两个js文件的差异性对比,共有两处不同)
然后再次运行on_time06.py文件,浏览器网址栏输入:http://127.0.0.1:5000/total_flights_chart_2,回车后输出结果如下。