综合设计——多源异构数据采集与融合应用综合实践
102202143 梁锦盛
职途启航
数据采集项目实践 | https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology |
---|---|
组名、项目简介 | 组别:数据矿工,项目需求:爬取招聘网站的求助信息、编辑信息匹配系统等,项目目标:根据求职者的个人信息为其推荐最合适的工作、根据全国各省的各行业信息为求职者提供合适的参考城市、项目开展技术路线:数据库操作:使用 pymysql 库与 MySQL 数据库进行交互,执行 SQL 查询和获取数据、Flask Web 框架:使用了 Flask 作为 Web 应用框架,用于创建 Web 服务和 API 端点 、WSGI 服务器 :pywsgi 作为 WSGI 服务器来运行 Flask 应用 |
团队成员学号 | 102202132、102202131、102202143、102202111、102202122、102202136 |
这个项目的目标 | 根据求职者的个人信息为其推荐最合适的工作 |
其他参考文献 | 无 |
Gitee链接 | https://gitee.com/zheng-bingzhi/2022-level-data-collection/tree/master/职业规划与就业分析平台 |
项目概述:
互联网的发展成就了众多招聘APP,这些APP为求职者提供了更多的就业选择,但随着行业的细分化,许多求职者甚至不清楚以自己的技能和工作经历适合什么工作岗位。俗话说良禽择木而栖,不同的城市主要的发展行业不同,这也就导致相同行业在不同城市的薪资待遇和发展前景截然不同,因此选择一个好城市也十分重要。本项目便是为求职者匹配合适的招聘信息和为求职者提供各省份间的各行业发展,为求职者提供参考。职途启航是一个综合性的在线工具,旨在通过数据可视化和智能推荐系统,为用户提供对经济趋势的深入理解和个性化的职业规划服务。职途启航集成了多维度的经济数据分析和个性化职业推荐两大核心功能,为用户提供了一个全面、直观、交互式的决策支持工具。
核心功能
-
经济数据可视化
- 多维度数据展示:展示各省各行业在2014至2023年间的就业人数变化、平均工资趋势等关键经济指标。
- 时间序列分析:通过长期数据观察,分析行业发展趋势。
- 多行业对比:在同一图表上对比不同行业的数据,快速识别行业增长和挑战。
-
个性化职业推荐
- 用户输入:用户可以输入职业期望、期望薪资、简历和工作经验等信息。
- 智能匹配:系统分析用户输入,匹配最合适的岗位。
- 推荐结果:提供10个最符合用户要求的岗位推荐。
技术实现
-
数据可视化技术
- ECharts图表库:使用ECharts实现丰富的图表类型和高度定制化的数据展示。
- 响应式设计:确保图表在不同设备和屏幕尺寸上都能良好展示。
- 交互式操作:支持图例点击隐藏、数据悬停显示等交互操作。
-
智能推荐算法
- 数据分析:运用数据分析技术处理用户输入和岗位数据库。
- 机器学习:采用机器学习算法进行岗位匹配和推荐。
- 实时反馈:系统提供实时反馈,用户提交信息后迅速获得推荐结果。
用户界面
- 直观的图表展示:用户可以通过图表直观地看到各省份及各行业经济数据和趋势。
- 简洁的输入表单:用户可以通过简洁的表单输入个人职业信息。
- 清晰的推荐列表:推荐的岗位以清晰的列表形式展示,便于用户浏览和比较。
市场优势
- 个性化服务:提供真正的个性化推荐,考虑到用户的具体需求和背景。
- 高效率:用户可以快速获得推荐结果,无需花费大量时间搜索和筛选岗位。
- 数据可靠性:推荐基于最新的行业数据和趋势,确保推荐的相关性和准确性。
- 直观展示与高信息密度:结果的直观展示和高信息密度使得用户可以快速把握关键信息。
系统价值
- 教育与研究:为学生和研究人员提供深入的经济数据分析工具。
- 职业规划:为求职者提供个性化的职业推荐和规划服务。
- 决策支持:为决策者提供基于数据的决策支持,帮助快速把握行业趋势和职业机会。
总结
经济数据与职业规划可视化分析平台以其全面性、易用性、定制化、实时性、直观性、高信息密度等特点满足用户需求。它不仅为用户带来了便捷的数据分析工具,也为教育和职业规划提供了强有力的支持。
数据采集:
- 爬取BOSS直聘和58同城等招聘网站收集薪资待遇,公司地点,公司福利等招聘信息
- 爬取国家统计局各省份的不同行业平均工资和就业人数2014-2022年的变化
- 爬取中国报告大厅各行业的多维度经济数据
- 将获取的招聘信息存储在云数据库中以便后续的匹配推荐
个人分工
一.各行业多维度经济数据爬取
从 中国报告大厅网站 (chinabgao.com) 上爬取统计数据,尤其是表格数据,并将这些数据保存在 CSV 文件中。项目涉及多个重要步骤和功能模块,我将对每个模块进行详细阐述,以便理解整体架构和每个部分的工作流程。
1. 爬取链接:
通过访问网站上的某些页面,我首先抓取包含表格数据的链接。这些链接在页面的特定 div
元素中。我使用了正则表达式和 BeautifulSoup
来从 HTML 中提取所有相关的链接。
任务:
- 从网页中抓取所有符合条件的链接。
- 逐一访问这些链接并解析页面内容。
流程:
- 访问网站,定位到包含所有链接的
div
元素。 - 提取所有
href
属性值,将它们保存在列表中。 - 将提取到的链接保存到
links.csv
文件中,确保每个链接都可以被后续访问和抓取。
2. 读取链接并爬取表格数据:
将所有链接提取并保存在 CSV 文件中,接下来读取这个文件,并逐个访问每个链接,爬取其中的表格数据。
任务:
- 从
links.csv
中读取所有链接。 - 访问每个链接,爬取页面中的表格数据(标题、表头、行数据)。
- 将抓取到的数据存入 CSV 文件中,按照页面标题命名文件。
流程:
- 读取
links.csv
文件中的所有链接。 - 对每个链接,使用
requests
库发送请求,获取网页内容。 - 使用
BeautifulSoup
对页面进行解析,提取表格数据:- 获取页面标题作为文件名。
- 获取表格的表头 (
th
) 和数据行 (td
)。
- 将提取的表头和数据行存储到 CSV 文件中。
- 设置延时 (
time.sleep
) 以避免频繁请求造成反爬虫封锁。
3. 数据存储:
爬取到的每个表格数据将被存储到一个独立的 CSV 文件中。这些文件将放置在名为 data
的新文件夹中,文件名为每个表格的标题(经过清理特殊字符后的标题)。
任务:
- 确保将每个页面的数据存储到单独的 CSV 文件中。
- 文件存储路径为
data
文件夹,确保文件夹存在(如果不存在,创建它)。 - 文件名必须基于页面标题,并进行清理,以去除不合法字符。
流程:
- 创建一个名为
data
的文件夹(如果尚未存在)。 - 使用标题作为 CSV 文件名,清理掉不合法字符(如
:
、/
)。 - 使用
csv
模块将表头和数据行写入对应的文件中。
挑战:
- 文件名中的非法字符需要处理,比如文件名不能包含
:
、/
、\\
等。
4. 请求头与反爬虫处理:
为了应对网站的反爬虫机制,为每个请求添加适当的请求头,模仿真实的用户请求。这部分工作包括了 User-Agent
、Accept
、Referer
等 HTTP 请求头的设置。
任务:
- 使用合适的请求头来伪装成浏览器请求。
- 添加适当的延时 (
time.sleep
) 来模拟人类操作,防止过于频繁的请求被识别为爬虫行为。
流程:
- 设置
User-Agent
、Accept
、Accept-Language
等请求头,以模拟浏览器访问。 - 在请求之间添加适当的延时(例如 3 秒),避免网站因请求过于频繁而封禁 IP。
- 使用
requests.Session()
来保持会话,确保请求头在多个请求之间保持一致。
挑战:
- 请求头的配置需要调整,根据实际情况,可能需要加入更多的头部信息(例如
Referer
或Origin
)。 - 尝试通过延时和调整请求频率来避免反爬虫技术的干扰。
5.代码:
import csv
import time
import os
import requests
from bs4 import BeautifulSoup
# 请求头信息,防止反爬虫
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
}
# 从 links.csv 中读取所有链接
def read_links_from_csv(file_path):
links = []
try:
with open(file_path, mode='r', encoding='utf-8') as file:
reader = csv.reader(file)
next(reader) # 跳过表头
for row in reader:
if row: # 确保行非空
links.append(row[0])
except Exception as e:
print(f"读取 links.csv 文件时发生错误: {e}")
return links
# 从页面中提取表格数据
def fetch_and_parse_table_data(url,headers):
try:
# 使用 requests 会话保持请求头信息
with requests.Session() as session:
session.headers.update(headers)
response = session.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
# 提取标题,存为文件名
title_tag = soup.find('div', class_='arctitle').find('h1')
title = title_tag.get_text(strip=True) if title_tag else "无标题"
# 提取表格
table = soup.find('table', style='width:100%; text-align:center;')
if table:
headers = []
rows = []
# 提取表头
th_elements = table.find_all('th')
for th in th_elements:
headers.append(th.get_text(strip=True))
# 提取表格数据
tr_elements = table.find_all('tr')[1:] # 忽略表头的tr
for tr in tr_elements:
td_elements = tr.find_all('td')
row = [td.get_text(strip=True) for td in td_elements]
rows.append(row)
return title, headers, rows
else:
print(f"页面 {url} 中未找到表格。")
else:
print(f"请求 {url} 时失败,状态码:{response.status_code}")
except Exception as e:
print(f"访问 {url} 时发生错误: {e}")
return None, None, None # 如果发生错误返回 None
# 将爬取的表格数据存入 CSV 文件
def save_to_csv(headers, rows, filename):
# 创建 'data' 文件夹(如果不存在)
if not os.path.exists('data'):
os.makedirs('data')
try:
# 将 CSV 文件存储到 'data' 文件夹中
file_path = os.path.join('data', filename)
with open(file_path, mode='w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerow(headers) # 写入表头
writer.writerows(rows) # 写入表格数据
print(f"表格数据已保存到 {file_path} 文件。")
except Exception as e:
print(f"写入CSV文件时发生错误: {e}")
# 主程序,逐个访问链接并爬取表格数据
def main():
links = read_links_from_csv('links.csv') # 读取 CSV 文件中的链接
print(f"读取到 {len(links)} 个链接,开始访问并爬取数据...")
for link in links:
title, head, rows = fetch_and_parse_table_data(link,headers)
if title and head and rows:
# 生成 CSV 文件名
csv_filename = f"{title}.csv".replace(" ", "_").replace("/", "_").replace(":", "_") # 清理文件名
save_to_csv(head, rows, csv_filename) # 保存数据到 CSV 文件
# 防止频繁访问导致被封,加入延时
time.sleep(3) # 每次请求后暂停3秒
else:
print(f"在链接 {link} 中未能成功获取数据。")
print("所有数据已成功保存为多个 CSV 文件。")
# 执行主程序
if __name__ == "__main__":
main()
二.各省各行业平均工资及就业人数可视化
-
数据处理:
- 从提供的Excel文件中提取相关数据,包括各年份和行业的城镇单位就业人员平均工资。
-
ECharts图表配置:
- 根据提取的数据,使用ECharts库生成图表配置代码。
- 配置图表的标题、工具提示、图例、工具箱、网格、坐标轴等基本属性。
- 为每个行业创建一个数据系列,并设置名称、类型、堆叠方式、区域样式等。
- 将数据填充到对应的系列中。
-
HTML模板整合:
- 将生成的ECharts配置代码整合到HTML文件中。
- 确保HTML文件中包含必要的ECharts库引用。
-
代码调试与优化:
- 确保图表能够正确渲染,并在不同设备和屏幕尺寸下自适应。
- 对代码进行调试,修复可能出现的任何错误或问题。
-
示例代码:
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
<title>北京市城镇单位就业人员平均工资变化趋势</title>
<script type="text/javascript"
src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<script type="text/javascript">
// 创建一个包含图表数据的数组
var chartData = [
{
name: '城镇单位就业人员平均工资',
data: [102268, 111390, 119928, 131700, 145766, 166803, 178178, 194651, 208977]
},
{
name: '农、林、牧、渔业城镇单位就业人员平均工资',
data: [49478, 50797, 51941, 55218, 59015, 93835, 83332, 77376, 78248]
},
{
name: '采矿业城镇单位就业人员平均工资',
data: [90402, 88360, 91017, 101975, 123959, 134956, 137130, 152773, 166806]
},
{
name: '制造业城镇单位就业人员平均工资',
data: [80418, 88934, 97600, 106835, 121299, 138312, 148777, 169210, 182324]
},
{
name: '电力、燃气及水的生产和供应业城镇单位就业人员平均工资',
data: [112136, 129350, 134474, 148142, 160386, 176707, 186760, 198210, 206786]
},
{
name: '建筑业城镇单位就业人员平均工资',
data: [77359, 82251, 89464, 99718, 114631, 127711, 134678, 146308, 152746]
},
{
name: '交通运输、仓储和邮政业城镇单位就业人员平均工资',
data: [78183, 81695, 90682, 97567, 107828, 123277, 122947, 134361, 146207]
},
{
name: '信息传输、计算机服务和软件业城镇单位就业人员平均工资',
data: [148828, 159486, 170531, 183183, 205834, 234121, 259729, 290038, 318742]
},
{
name: '批发和零售业城镇单位就业人员平均工资',
data: [91976, 94542, 98863, 107731, 123713, 150238, 167745, 180062, 194228]
},
{
name: '住宿和餐饮业城镇单位就业人员平均工资',
data: [48870, 51955, 54814, 56325, 58156, 60870, 58283, 63642, 64967]
},
{
name: '金融业城镇单位就业人员平均工资',
data: [225482, 248320, 239085, 253637, 266921, 256979, 260508, 298200, 334515]
},
{
name: '房地产业城镇单位就业人员平均工资',
data: [79280, 85247, 92832, 97369, 101346, 110044, 116230, 131866, 125251]
},
{
name: '租赁和商务服务业城镇单位就业人员平均工资',
data: [106540, 109031, 119151, 123966, 127507, 148567, 156427, 168331, 176281]
},
{
name: '科学研究、技术服务和地质勘查业城镇单位就业人员平均工资',
data: [124123, 132339, 139990, 150611, 170139, 196767, 200894, 215797, 230803]
},
{
name: '水利、环境和公共设施管理业城镇单位就业人员平均工资',
data: [64725, 72666, 76948, 87538, 94369, 107790, 113766, 114095, 121021]
},
{
name: '居民服务和其他服务业城镇单位就业人员平均工资',
data: [45776, 48613, 52025, 55509, 57182, 81465, 73883, 78845, 81607]
},
{
name: '教育城镇单位就业人员平均工资',
data: [99337, 111417, 120573, 143215, 161029, 181240, 196511, 201129, 216740]
},
{
name: '卫生、社会保障和社会福利业城镇单位就业人员平均工资',
data: [125273, 139176, 147903, 169191, 187390, 208481, 201025, 216920, 230767]
},
{
name: '文化、体育和娱乐业城镇单位就业人员平均工资',
data: [121094, 130134, 139087, 150810, 173632, 205405, 221193, 224007, 227639]
},
{
name: '公共管理和社会组织城镇单位就业人员平均工资',
data: [76226, 91030, 101999, 124864, 140310, 159193, 180110, 176154, 188568]
}
];
var dom = document.getElementById("container");
var myChart = echarts.init(dom, null, { renderer: 'canvas', useDirtyRect: false });
const years = ['2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022'];
// 配置图表
var option;
option = {
title: {
text: '北京市城镇单位就业人员平均工资变化趋势'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: chartData.map(item => item.name),
top: '15%'
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: years
},
yAxis: {
type: 'value',
name: '平均工资(元)'
},
series: chartData.map(item => ({
name: item.name,
type: 'line',
stack: '总量',
areaStyle: {},
data: item.data,
emphasis: {
focus: 'series'
}
}))
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
// 监听窗口大小变化
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
三.各行业多维数据2024年1-9月可视化:
-
数据处理:
- 您需要将从不同CSV文件中提取的数据整理成一个统一的格式,以便在图表中展示。这包括处理各个指标的数据,如利润总额、平均用工人数、所有者权益合计等。
-
图表设计:
- 设计图表的布局和样式,包括坐标轴、图例、提示框等。
- 确定哪些数据系列将以折线图展示,哪些以柱状图展示,以及它们的Y轴配置。
-
代码实现:
- 编写HTML和JavaScript代码来初始化ECharts实例,并设置图表的配置项(
option
对象)。 - 将处理好的数据映射到ECharts的
series
配置中,确保每个数据系列都能正确显示在图表上。
- 编写HTML和JavaScript代码来初始化ECharts实例,并设置图表的配置项(
-
功能实现:
- 实现图表的交互功能,如工具箱中的“保存为图片”功能。
- 确保图表的响应性和适应性,使其在不同设备和屏幕尺寸上都能正确显示。
-
示例代码:
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset="utf-8">
<title>ECharts Statistics</title>
<!-- 引入 ECharts 文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.3.3/echarts.min.js"></script>
</head>
<body style="height: 100%; margin: 0">
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="height: 100%"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 数据
var data = [
{ time: '2024年2月', 亏损企业单位数: 11322, 亏损企业单位数同期: 12289, 亏损企业单位数增减: -7.9,
利润总额: 418.1, 利润总额同期: 134.5, 利润总额增长: 210.9,
平均用工人数: 836.8, 平均用工人数同期: 857.6, 平均用工人数增长: -2.4,
企业单位数: 28244, 所有者权益合计: 85809.5, 所有者权益合计同期: 78705.8, 所有者权益合计增长: 9,
投资收益: 54.6, 投资收益同期: 33.7, 投资收益增长: 62,
销售费用: 456.9, 销售费用同期: 401.9, 销售费用增长: 13.7 },
{ time: '2024年3月', 亏损企业单位数: 11845, 亏损企业单位数同期: 12218, 亏损企业单位数增减: -3.1,
利润总额: 1008.5, 利润总额同期: 552.5, 利润总额增长: 82.5,
平均用工人数: 849.3, 平均用工人数同期: 861.9, 平均用工人数增长: -1.5,
企业单位数: 28258, 所有者权益合计: 86219.7, 所有者权益合计同期: 79087.8, 所有者权益合计增长: 9,
投资收益: 131, 投资收益同期: 107.8, 投资收益增长: 21.5,
销售费用: 741.8, 销售费用同期: 691.9, 销售费用增长: 7.2 },
{ time: '2024年4月', 亏损企业单位数: 10522, 亏损企业单位数同期: 10925, 亏损企业单位数增减: -3.7,
利润总额: 1441.7, 利润总额同期: 820, 利润总额增长: 75.8,
平均用工人数: 857.3, 平均用工人数同期: 863.7, 平均用工人数增长: -0.7,
企业单位数: 28279, 所有者权益合计: 86835, 所有者权益合计同期: 79451.1, 所有者权益合计增长: 9.3,
投资收益: 168.8, 投资收益同期: 143, 投资收益增长: 18,
销售费用: 985.4, 销售费用同期: 919.3, 销售费用增长: 7.2 },
{ time: '2024年5月', 亏损企业单位数: 10066, 亏损企业单位数同期: 10348, 亏损企业单位数增减: -2.7,
利润总额: 1945.6, 利润总额同期: 1241.1, 利润总额增长: 56.8,
平均用工人数: 862.3, 平均用工人数同期: 863.2, 平均用工人数增长: -0.1,
企业单位数: 28303, 所有者权益合计: 86965.1, 所有者权益合计同期: 79782.9, 所有者权益合计增长: 9,
投资收益: 271.9, 投资收益同期: 246.2, 投资收益增长: 10.4,
销售费用: 1234.6, 销售费用同期: 1150.6, 销售费用增长: 7.3 },
{ time: '2024年6月', 亏损企业单位数: 9935, 亏损企业单位数同期: 10000, 亏损企业单位数增减: -0.7,
利润总额: 2942, 利润总额同期: 2373.3, 利润总额增长: 24,
平均用工人数: 868.2, 平均用工人数同期: 866.7, 平均用工人数增长: 0.2,
企业单位数: 28390, 所有者权益合计: 87466, 所有者权益合计同期: 81228.8, 所有者权益合计增长: 7.7,
投资收益: 491.9, 投资收益同期: 334.4, 投资收益增长: 47.1,
销售费用: 1532, 销售费用同期: 1475.6, 销售费用增长: 3.8 },
{ time: '2024年7月', 亏损企业单位数: 9629, 亏损企业单位数同期: 9710, 亏损企业单位数增减: -0.8,
利润总额: 3362.1, 利润总额同期: 2688.1, 利润总额增长: 25.1,
平均用工人数: 869.2, 平均用工人数同期: 869.2, 平均用工人数增长: 0,
企业单位数: 28457, 所有者权益合计: 88065.8, 所有者权益合计同期: 81734, 所有者权益合计增长: 7.7,
投资收益: 527.2, 投资收益同期: 386.6, 投资收益增长: 36.4,
销售费用: 1773, 销售费用同期: 1711.4, 销售费用增长: 3.6 },
{ time: '2024年8月', 亏损企业单位数: 9447, 亏损企业单位数同期: 9343, 亏损企业单位数增减: 1.1,
利润总额: 3927.5, 利润总额同期: 3216.9, 利润总额增长: 22.1,
平均用工人数: 874.7, 平均用工人数同期: 873.3, 平均用工人数增长: 0.2,
企业单位数: 28507, 所有者权益合计: 88866.5, 所有者权益合计同期: 83151.4, 所有者权益合计增长: 6.9,
投资收益: 784.3, 投资收益同期: 493.4, 投资收益增长: 59,
销售费用: 2019.5, 销售费用同期: 1947.7, 销售费用增长: 3.7 },
{ time: '2024年9月', 亏损企业单位数: 9436, 亏损企业单位数同期: 9187, 亏损企业单位数增减: 2.7,
利润总额: 4503.4, 利润总额同期: 4203.4, 利润总额增长: 7.1,
平均用工人数: 879.9, 平均用工人数同期: 878.6, 平均用工人数增长: 0.1,
企业单位数: 28633, 所有者权益合计: 89655.1, 所有者权益合计同期: 84054.6, 所有者权益合计增长: 6.7,
投资收益: 913.4, 投资收益同期: 631, 投资收益增长: 44.8,
销售费用: 2307.4, 销售费用同期: 2237.1, 销售费用增长: 3.1 }
];
// 指定图表的配置项和数据
var option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: [
'亏损企业单位数', '亏损企业单位数同期', '亏损企业单位数增减',
'利润总额', '利润总额同期', '利润总额增长',
'平均用工人数', '平均用工人数同期', '平均用工人数增长',
'企业单位数', '所有者权益合计', '所有者权益合计同期', '所有者权益合计增长',
'投资收益', '投资收益同期', '投资收益增长',
'销售费用', '销售费用同期', '销售费用增长'
]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: data.map(function (item) {
return item.time;
})
},
yAxis: [
{
type: 'value',
name: '金额(亿元)',
axisLabel: {
formatter: '{value}'
},
position: 'left'
},
{
type: 'value',
name: '百分比(%)',
axisLabel: {
formatter: '{value}%'
},
position: 'right'
},
{
type: 'value',
name: '单位数(个)',
axisLabel: {
formatter: '{value}'
},
position: 'right'
}
],
series: [
{
name: '亏损企业单位数',
type: 'line',
yAxisIndex: 2,
data: data.map(function (item) {
return item.亏损企业单位数;
})
},
{
name: '亏损企业单位数同期',
type: 'line',
yAxisIndex: 2,
data: data.map(function (item) {
return item.亏损企业单位数同期;
})
},
{
name: '亏损企业单位数增减',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.亏损企业单位数增减;
})
},
{
name: '利润总额',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.利润总额;
})
},
{
name: '利润总额同期',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.利润总额同期;
})
},
{
name: '利润总额增长',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.利润总额增长;
})
},
{
name: '平均用工人数',
type: 'line',
yAxisIndex: 2,
data: data.map(function (item) {
return item.平均用工人数;
})
},
{
name: '平均用工人数同期',
type: 'line',
yAxisIndex: 2,
data: data.map(function (item) {
return item.平均用工人数同期;
})
},
{
name: '平均用工人数增长',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.平均用工人数增长;
})
},
{
name: '企业单位数',
type: 'line',
yAxisIndex: 2,
data: data.map(function (item) {
return item.企业单位数;
})
},
{
name: '所有者权益合计',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.所有者权益合计;
})
},
{
name: '所有者权益合计同期',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.所有者权益合计同期;
})
},
{
name: '所有者权益合计增长',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.所有者权益合计增长;
})
},
{
name: '投资收益',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.投资收益;
})
},
{
name: '投资收益同期',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.投资收益同期;
})
},
{
name: '投资收益增长',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.投资收益增长;
})
},
{
name: '销售费用',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.销售费用;
})
},
{
name: '销售费用同期',
type: 'line',
yAxisIndex: 0,
data: data.map(function (item) {
return item.销售费用同期;
})
},
{
name: '销售费用增长',
type: 'bar',
yAxisIndex: 1,
data: data.map(function (item) {
return item.销售费用增长;
})
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
四.接入星火大模型回答用户问题:
代码(省略密钥信息):
from flask import Flask, request, jsonify
import SparkApi
from flask import render_template
import time
app = Flask(__name__)
# 填写控制台中获取的密钥信息
appid = "f7"
api_secret = "MDlh"
api_key = "9e5be"
# 选择版本
domain = "4.0Ultra"
Spark_url = "wss://spark-api.xf-yun.com/v4.0/chat"
text = []
def getText(role, content):
jsoncon = {"role": role, "content": content}
text.append(jsoncon)
return text
def getlength(text):
length = 0
for content in text:
leng = len(content["content"])
length += leng
return length
def checklen(text):
while getlength(text) > 8000:
del text[0]
return text
from flask import render_template
@app.route('/')
def index():
return render_template('1.html') # 确保有一个index.html文件
@app.route('/ask', methods=['POST'])
def ask():
user_question = request.json.get('question')
if not user_question:
return jsonify({'answer': '请提供问题!'})
question = checklen(getText("user", user_question))
SparkApi.answer = ""
# 调用SparkAPI获取回答
SparkApi.main(appid, api_key, api_secret, Spark_url, domain, question)
# 假设SparkApi.answer已经获取了响应的结果
answer = SparkApi.answer if SparkApi.answer else "没有得到回答,请稍后再试。"
return jsonify({'answer': answer})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
总结
在项目实践中,学习和体验了许多宝贵的知识和技能,以下是一些总结和感想:
技术技能提升
-
数据可视化技术:通过使用ECharts等数据可视化工具,我深入学习了如何将复杂的数据转化为直观的图表,这不仅增强了我的技术能力,也提高了我对数据的理解力。
-
前后端开发:项目中涉及到的前端表单设计和后端服务器管理,让我对全栈开发有了更全面的理解。
个人成长与感悟
-
解决问题的能力:在项目中遇到各种挑战和问题,我学会了如何冷静分析问题并找到有效的解决方案。
-
持续学习:技术日新月异,项目实践让我认识到了持续学习的重要性,以及如何快速掌握新技术。
-
用户体验意识:通过设计用户界面和体验,我更加重视用户体验,理解了好的产品需要从用户的角度出发。
结论
总的来说,这个项目不仅是一个技术实践的平台,也是一个学习和成长的环境。我不仅提升了自己的技术能力,也增强了团队协作的能力。更重要的是,我学会了如何将理论知识应用到实际问题中,以及如何在快速变化的技术领域中保持竞争力。这些经验和技能将对我的未来职业发展产生深远的影响。