”明月如霜,好风如水,清景无限 “
想画出最炫酷的图,用matplotlib还是很难的,不是无法完成,而是过于繁琐。之前也尝试过plotly画图,也是属于交互性的图,即可以保存成本地的html。先看一下echarts模板吧。
具体的网址:
https://echarts.apache.org/examples/zh/index.html#chart-type-pie
壹
首先是,爬一点演示数据。
其实看到这个实时票房,你应该知道是动态加载的。不过咱们还是试一试,主要是我文远好久没玩selenium了。
import requests
from lxml import etree
url = "https://www.endata.com.cn/BoxOffice/BO/RealTime/reTimeBO.html"
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'
}
response=requests.get(url=url,headers=headers)
response.encoding='utf-8'
page=response.text
print(page)
page_html = etree.HTML(page)
tr_list=page_html.xpath('//*[@id="TB_Retime"]/tbody/tr')
print("*"*100)
print("tr_list:",len(tr_list))
print("*"*100)
果然不行,正好回顾一下selenium吧。(尽量简洁)
from selenium import webdriver
import time
import os
wd = webdriver.Chrome()
wd.implicitly_wait(5)
wd.get('https://www.endata.com.cn/BoxOffice/BO/RealTime/reTimeBO.html')
tr_list=wd.find_elements_by_xpath('//*[@id="TB_Retime"]/tbody/tr')
print(len(tr_list))
for tr in tr_list:
title=tr.get_attribute('title')
# BoX_office=tr.find_element_by_xpath('./td[3]').text
BoX_office=tr.find_element_by_css_selector('td:nth-child(3)').text
if not os.path.exists('./data.csv'):
with open('./data.csv','a+',encoding='utf-8') as f:
f.write(title+','+BoX_office+'\n')
time.sleep(0.3)
wd.quit()
注意:find_elements_by_xpath只能找元素,不能像之前一样,直接text到底得到文本。需要以元素对象为基础,调用text属性。获取某些属性值用方法:get_attribute。同时记得加上wd.implicitly_wait(5),不然容易代码比响应快导致报错。最后提一下,浏览器的驱动最好还是放到python解释器同一路径下,不然webdriver.Chrome()里面的路径参数还是很烦人的。
贰
现在是要把这些数据显示在网页上,看一看echarts官网上的对应模板,发现数据是list里装dict的结构。因此需要先转一下数据:
data = pd.read_csv('./data.csv',header=None)
data.rename(columns={0:"name" , 1:"value"}, inplace=True)
#数据转换为 [{},{}]
data_list=data.to_dict(orient='records')
这个时候同时提到的是一个最简单的flask框架使用。自行安装。
from flask import Flask, render_template
import pandas as pd
app = Flask(__name__)
@app.route("/")
def show():
data = pd.read_csv('./data.csv',header=None)
data.rename(columns={0:"name" , 1:"value"}, inplace=True)
#数据转换为 [{},{}]
data_list=data.to_dict(orient='records')
# print(data_list)
return render_template("echart.html",data=data_list)
if __name__ == "__main__":
app.run(debug=True)
# app.run(debug=True)
咱们的流程是,flask给出本地的url,当我们访问url时,由装饰器路由到show(),从而网页会接受响应,内容就是echart.html。(附带传参data)
此处的大坑是,计算机的名称一定要是英文。文远因为名字,折腾了好半天,详情如下:
https://blog.csdn.net/qq_41109668/article/details/82908455
那么只剩最后一个问题了,可这是个前端的问题。不仅是html,还包括css和js。所以该如何解决呢。
叁
!!!套模板,也就是开头提到的网站。
建议直接套下面:(记得此文件一定要放在本层路径新建名叫template的文件夹下面)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.0.0-rc.1/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<!-- <div id="main" style="width: 1200px;height:800px; background: rgb(248, 189, 199);"></div> -->
<div id="main" style="position:absolute;z-index:-1;width:100%;height:100%;top:0px;left:0px;font-size: 20px; background: rgb(245, 195, 232);"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
backgroundColor: '#84AF9B',
title: {
text: '实时电影票房',
left: 'center',
top: 20,
textStyle: {
color: '#ccc',
fontSize: 30
}
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
visualMap: {
// show: false,
min: 0,
max: 1000,
inRange: {
colorLightness: [0, 1]
}
},
series: [
{
name: '电影票房',
type: 'pie',
radius: '80%',
center: ['50%', '50%'],
data: {{data|tojson}}.sort(function (a, b) { return a.value - b.value; }),
roseType: 'radius',
label: {
color: 'rgba(10, 10, 10, 0.8)',
fontSize: 15
// font-size: 12px;
},
labelLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)'
},
smooth: 0.2,
length: 10,
length2: 20
},
itemStyle: {
color: '#c23531',
shadowBlur: 200,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return Math.random() * 100;
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
配上官方文档,号称5min学废:
https://echarts.apache.org/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts
就是挺简单的,你只需要操作画图部分。也就是 var option = {};
这里具体的问题就看你的模板好不好用。
肆
本来数据应该是这样:
data: [{'name': '送你一朵小红花', 'value': 960.24},
{'name': '缉魂', 'value': 814.72},
{'name': '许愿神龙', 'value': 684.15},
{'name': '拆弹专家2', 'value': 391.72},
{'name': '温暖的抱抱', 'value': 294.11},
{'name': '心灵奇旅', 'value': 248.77},
{'name': '没有过不去的年', 'value': 120.91},
{'name': '叱咤风云', 'value': 97.78},
{'name': '点点星光', 'value': 40.22},
{'name': '老爷保号', 'value': 39.54},
{'name': '其它', 'value': 86.82}].sort(function (a, b) { return a.value - b.value; }),
这届涉及到传参,也就是将爬到的参数,传到html+css+js文件里。也就是这句:(等价于上面一坨)
data: {{data|tojson}}.sort(function (a, b) { return a.value - b.value; }),
行了,具体效果如下:(手机上打开的)
自己看动态数据本地文件吧。也没服务器,文远太难了。
对你有帮助的话,记得点赞并且把公众号设为星标哦。
END
作者:不爱跑马的影迷不是好程序猿
喜欢的话请关注点赞👇 👇👇 👇
壹句: 欲买桂花同载酒