在 外行學 Python 爬蟲 第九篇 讀取數據庫中的數據 中完成了使用 API 從數據庫中讀取所需要的數據,但是返回的是 JSON 格式,看到的是一串的字符串數據不是很好理解,這篇將介紹如何將數據進行可視化。
數據可視化選用 pyecharts 來完成,通過將 pyecharts 集成到 Flask 中完成數據從數據庫到網頁可視化顯示的過程。最終完成後通過選擇框選中相應的生產商後,即可查看在立創商城上該廠商所生產各種元件的數量,如下圖所示:
pyecharts 是利用 Echarts 生成圖標的 Python 類庫,是一款強大的數據可視化工具。更多信息請查閱 pyecharts 官網。
準備工作
pyecharts 安裝
pyecharts 可使用 pip 進行安裝
pip install pyecharts
也可以使用源碼進行安裝
$ git clone https://github.com/pyecharts/pyecharts.git
$ cd pyecharts
$ pip install -r requirements.txt
$ python setup.py install
推薦使用 pip 進行安裝,特別是對於初學者來說。
集成到 Flask 中
需要將 pyecharts 中的模板拷貝到 Flask 目錄下的 templates 目錄中,模板文件位於 pyecharts/pyecharts/render/templates/
目錄中。
實際上此時即可在 Flask 中使用 pyecharts 了,但是根據 pyecharts 文檔中的介紹,在實際使用過程中遇到了以下錯誤
jinja2.exceptions.TemplateNotFound: simple_chart.html
該錯誤是由以下配置引起的
CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))
將該配置從代碼中刪除,重新運行程序即可看到完整的圖標信息。
爬蟲數據可視化
在這裏將完成從數據庫中讀取各生產商所生產各類元件的數據,通過 Echarts 進行可視化的操作。爲了實現能夠通過選擇生產商實時更新圖表數據,最終使用前後端分離的方法實現數據顯示。
首先,先看下 HTML 文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<select id="brand_name" onchange="showBrandBar()">
{% for brand in brands %}
<option value="{{brand}}">{{brand}}</option>
{% endfor %}
</select>
<div id="bar" style="width:1000px; height:600px;"></div>
<script>
$(
showBrandBar()
)
function showBrandBar() {
var selId = document.getElementById("brand_name");
var value = selId.options[selId.selectedIndex].value;
console.log(value)
postBrandBar(value)
}
function postBrandBar(brand_name) {
var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
$.ajax({
type: "POST",
url: "http://127.0.0.1:5000/brand/bar",
dataType: 'json',
data:JSON.stringify({
name: brand_name
}),
success: function (result) {
chart.setOption(result);
}
});
}
</script>
</body>
</html>
採用 ajax 來響應 select 標籤的改變事件,通過 ajax 向服務端提交當前選中的生產商,同時從服務器獲取該廠商的信息。可以看到在 javascrpit 腳本中默認執行了一次 showBrandBar() 函數,是爲了在第一次加載頁面時能夠正常顯示圖標,否則第一次加載頁面時圖表位置將是空白。
在 Flask 的後端需要實現一個 get 方法和一個 post 方法。get 方法用來獲取所有的生產商名稱,同時向瀏覽器發送 html 頁面;post 方法用來相應 html 頁面中的 ajax 請求,發送該生產商所提供的各類元件的數量。
get 方法的代碼如下
def get(self):
brands = [name[0] for name in db.session.query(Brands.name).all()]
return render_template('brand_bar.html', brands=brands)
post 方法的代碼如下
def post(self):
jsons = request.get_json(force=True)
brand_name = jsons['name']
brand_id = db.session.query(Brands.id).filter(Brands.name == brand_name).one()[0]
catalog_ids = db.session.query(Catalog.id, Catalog.name).filter(Catalog.parent_id==None).all()
catalog_name = []
catalog_count = []
for cata_id, name in catalog_ids:
catalog_name.append(name)
count = db.session.query(Materials).join(Catalog).filter(
Materials.brand_id == brand_id).filter(
Catalog.parent_id == cata_id).count()
catalog_count.append(count)
c = (
Bar()
.add_xaxis(catalog_name)
.add_yaxis('數量', catalog_count)
.set_global_opts(
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-90)),
title_opts=opts.TitleOpts(title=brand_name, subtitle="物料數量"),
)
)
return c.dump_options_with_quotes()
在 post 方法中主要做的是數據的查詢,通過生產商名稱來查詢出該生產商在數據中的 id,從而獲取其所提供的所有元件,然後按照 Catalog 中的分類獲取其各個分類中的元件數據。將相應的數據填入 pyecharts 的 Bar 對象中回傳給 ajax 請求。
至此,執行程序在瀏覽器中即可看到在文章開頭所看到的頁面,選擇不同的生產商圖標將實時更新到該生產商的信息。