【java爬虫】获取个股详细数据并用echarts展示

前言

前面一篇文章介绍了获取个股数据的方法,本文将会对获取的接口进行一些优化,并且添加查询数据的接口,并且基于后端返回数据编写一个前端页面对数据进行展示。

具体的获取个股数据的接口可以看上一篇文章

【java爬虫】基于springboot+jdbcTemplate+sqlite+OkHttp获取个股的详细数据-CSDN博客

下面是操作演示,首先是爬虫获取股票数据

接着是进行获取个股详细数据并且进行数据展示

数据图表还可以下载下来,下面是下载下来的图片,不过下载下来的图片就不能查看每个点的详细数据了

后端接口

相对于前文,后端接口进行了一定优化,每年的数据分3次获取,时间段分别是0101-0501,0501-0901和0901-1231,并且每次请求都是从2023年开始逐年往前获取,一旦发现没有数据了就停止获取。

服务类的详细代码如下

@Slf4j
@Service
public class StockService {

    // 没有数据对应的返回
    private final String NO_DATA_RESPONSE1 = "historySearchHandler({})";
    private final String NO_DATA_RESPONSE2 = "history({})";

    @Autowired
    private SQLiteStockDao sqLiteStockDao;

    // 获取一个OKHttp实例
    private OkHttpClient client = new OkHttpClient()
            .newBuilder()
            .connectTimeout(1000, TimeUnit.SECONDS)
            .build();

    public void clearAll() {
        sqLiteStockDao.clearAll();
    }

    public void createTbaleIfNotExist() {
        sqLiteStockDao.createTbaleIfNotExist();
    }

    // 查询所有的数据
    public List<StockEntity> queryAllByCode(String code) {
        return sqLiteStockDao.queryAllByCode(code);
    }


    // 获取数据并且存入数据库
    // 三个参数分别是:股票代码,开始时间和结束时间
    // 开始时间和结束时间都填年份,代码中会自动补全具体时间
    public int getDataByYear(String code, String start, String end) {
        String url = "https://q.stock.sohu.com/hisHq?";
        Request request = null;
        Response response = null;
        int num = 0;
        // 一年的数据分三次请求
        String[] startTime = {"0101", "0501", "0901"};
        String[] endTime = {"0501", "0901", "1231"};
        try {
            for (int i = Integer.parseInt(end); i >= Integer.parseInt(start); i--) {
                for (int j = startTime.length-1; j >=0; j--) {
                    HttpUrl.Builder httpBuiler = HttpUrl.parse(url).newBuilder();
                    String starttime = i + startTime[j];
                    String endtime = i + endTime[j];
                    log.info("开始计算时间段[" + starttime + "," + endtime + "]内数据");
                    httpBuiler.addQueryParameter("code", "cn_" + code);
                    httpBuiler.addQueryParameter("start", starttime);
                    httpBuiler.addQueryParameter("end", endtime);
                    httpBuiler.addQueryParameter("stat", "1");
                    httpBuiler.addQueryParameter("order", "D");
                    httpBuiler.addQueryParameter("period", "d");
                    httpBuiler.addQueryParameter("callback", "history");
                    httpBuiler.addQueryParameter("rt", "jsonp");
                    request = new Request.Builder()
                            .url(httpBuiler.build())
                            .get()   //默认就是GET请求,可以不写
                            .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36")
                            .build();

                    response = client.newCall(request).execute();
                    String res = response.body().string();
                    log.info("请求得到的数据:" + res);
                    if (res.contains(NO_DATA_RESPONSE1) || res.contains(NO_DATA_RESPONSE2)) {
                        // 如果返回为空就认为后面没有数据了
                        log.info("时间段[" + starttime + "," + endtime + "]没有数据");
                        return num;
                    } else {
                        List<StockEntity> entities = parseStrToArr(res, code);
                        sqLiteStockDao.insertItems(entities);
                        log.info("时间段[" + starttime + "," + endtime + "]内有" + entities.size() + "条数据");
                        num += entities.size();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return num;
    }

    // 将string数据解析成List列表
    private List<StockEntity> parseStrToArr(String res, String code) {
        if (res.contains(NO_DATA_RESPONSE1) || res.contains(NO_DATA_RESPONSE2)) {
            return new ArrayList<>();
        }
        List<StockEntity> entities = new ArrayList<>();
        res = res.split("\\(\\[")[1].split("]\\)")[0];
        JSONObject jsonObject = JSON.parseObject(res);
        // 获取 hq 字段的值
        Object hq = jsonObject.get("hq");
        // 判断 hq 的值是否为数组
        if (hq instanceof JSONArray) {
            // 遍历数组
            for (Object arr : (JSONArray) hq) {
                JSONArray jsonArray = (JSONArray) arr;
                StockEntity entity = new StockEntity();
                entity.setRecord_date((String) jsonArray.get(0));
                Double open_price = Double.parseDouble((String) jsonArray.get(1));
                Double close_price = Double.parseDouble((String) jsonArray.get(2));
                Double change_amend = Double.parseDouble((String) jsonArray.get(3));
                Double change_range = Double.parseDouble(((String) jsonArray.get(4)).split("%")[0]);
                Double max_price = Double.parseDouble((String) jsonArray.get(5));
                Double min_price = Double.parseDouble((String) jsonArray.get(6));
                Double volume = Double.parseDouble((String) jsonArray.get(7));
                Double turnover = Double.parseDouble((String) jsonArray.get(8));
                Double turnover_rate = Double.parseDouble(((String) jsonArray.get(9)).split("%")[0]);
                entity.setOpen_price(open_price);
                entity.setClose_price(close_price);
                entity.setChange_amend(change_amend);
                entity.setChange_range(change_range);
                entity.setMax_price(max_price);
                entity.setMin_price(min_price);
                entity.setVolume(volume);
                entity.setTurnover(turnover);
                entity.setTurnover_rate(turnover_rate);
                entity.setCode(code);
                entity.setId(entity.getCode() + "_" + (String) jsonArray.get(0));
                entities.add(entity);
            }
        }
        return entities;
    }

}

Dao层新增了查询某一只股票详细数据的方法,详细代码如下

@Slf4j
@Repository
public class SQLiteStockDao implements StockDao {

    private final String TABLE_NAME = "stock_table";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void clearAll() {
        String sql = "DELETE FROM " + TABLE_NAME;
        jdbcTemplate.batchUpdate(sql);
        log.info("成功清空数据表" + TABLE_NAME);
    }

    @Override
    public void createTbaleIfNotExist() {
        Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name = ?", Integer.class, TABLE_NAME);
        if (count == 0) {
            String sql = "CREATE TABLE " + TABLE_NAME + "(" +
                    "id VARCHAR(50) PRIMARY KEY," +
                    "code VARCHAR(20)," +           // 股票代码
                    "record_date VARCHAR(20)," +    // 记录的时间
                    "open_price float," +           // 开盘价
                    "close_price float," +           // 收盘价
                    "change_ament float," +          // 涨跌额
                    "change_range float," +          // 涨跌幅
                    "max_price float," +             // 最高价格
                    "min_price float," +             // 最低价格
                    "volume float," +                // 成交量(手)
                    "turnover float," +              // 成交额(万)
                    "turnover_rate float)";               // 换手率
            jdbcTemplate.execute(sql);
            log.info(TABLE_NAME + "建表成功");
        } else {
            log.info("建表失败,表格已存在");
        }
    }

    @Override
    public void insertItems(List<StockEntity> entityList) {
        String sql = "INSERT OR IGNORE INTO " + TABLE_NAME + " (id, code, record_date," +
                "open_price, close_price, change_ament," +
                "change_range, max_price, min_price," +
                "volume, turnover, turnover_rate) values (?,?,?,?,?,?,?,?,?,?,?,?)";
        // 将列表转为Object数组
        List<Object[]> arr = new ArrayList<>();
        for(int i=0; i<entityList.size(); i++) {
            arr.add(entityList.get(i).changeToArray());
        }
        jdbcTemplate.batchUpdate(sql, arr);
    }

    @Override
    public List<StockEntity> queryAllByCode(String code) {
        String sql = "SELECT open_price, close_price, record_date, volume FROM " + TABLE_NAME +" WHERE code=? ORDER BY record_date DESC";
        log.info("执行sql:" + sql);
        List<StockEntity> stockEntities = jdbcTemplate.query(sql, new Object[]{code}, new BeanPropertyRowMapper<>(StockEntity.class));
        return stockEntities;
    }


}

Dao层对应的实体类如下

@Data
@NoArgsConstructor
@AllArgsConstructor
public class StockEntity {
    private String id;
    private String code;
    private String record_date;
    private Double open_price;
    private Double close_price;
    private Double change_amend;
    private Double change_range;
    private Double max_price;
    private Double min_price;
    private Double volume;
    private Double turnover;
    private Double turnover_rate;

    // 将数据转换为Object数组
    public Object[] changeToArray() {
        Object[] arr = new Object[]{
                id,
                code,
                record_date,
                open_price.toString(),
                close_price.toString(),
                change_amend.toString(),
                change_range.toString(),
                max_price.toString(),
                min_price.toString(),
                volume.toString(),
                turnover.toString(),
                turnover_rate.toString()
        };
        return arr;
    }

}

最后就是提供给前端调用的接口了,主要是获取某一只股票的数据,只需要传入股票代码就能开始获取数据,还有查询的接口,同样是输入股票代码进行查询,控制类的详细代码如下

@Controller
@CrossOrigin
@RequestMapping("/stock")
public class StockController {

    private final String START_YEAR = "1985";
    private final String END_YEAR = "2023";

    @Autowired
    private StockService stockService;

    @RequestMapping("/clear")
    @ResponseBody
    public String clear() {
        stockService.clearAll();
        return "success";
    }

    @RequestMapping("/createTable")
    @ResponseBody
    public String getData() {
        stockService.createTbaleIfNotExist();
        return "success";
    }

    @RequestMapping("/getDataByYear/{code}/{start}/{end}")
    @ResponseBody
    public String getDataByYear(@PathVariable("code") String code,
                                @PathVariable("start") String start,
                                @PathVariable("end") String end) {
        Integer num = stockService.getDataByYear(code, start, end);
        return num.toString();
    }

    @RequestMapping("/getData/{code}")
    @ResponseBody
    public String getData(@PathVariable("code") String code) {
        Integer num = stockService.getDataByYear(code, START_YEAR, END_YEAR);
        List<StockEntity> stockEntityList = stockService.queryAllByCode(code);
        return JSON.toJSONString(stockEntityList);
    }

    @RequestMapping("/queryData/{code}")
    @ResponseBody
    public String queryData(@PathVariable("code") String code) {
        List<StockEntity> stockEntityList = stockService.queryAllByCode(code);
        return JSON.toJSONString(stockEntityList);
    }
}

前端页面

下面来说一下前端页面的编写,前端页面一共分为三个大块,

  • 沪深300成分股数据和操作按钮,通过按钮可以进行数据获取或者数据展示
  • 个股详细数据,这一个表格的内容会在你选定具体的股票后变更
  • 数据展示,选定个股后会动态生成展示的数据

前端主要用了vue+element-plus+axios+echarts进行编写,echarts表格参数参考了官方示例,由于数据量比较大,所以选用了大数据量的图表,参考的地址如下

Examples - Apache ECharts

下面展示页面的详细代码

<template>
  <div>
    <el-row class="container">
      <div class="left-grid">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>沪深300成分股</span>
            </div>
          </template>
          <el-table
            :data="table_data"
            :show-header="true"
            :max-height="250"
            stripe
          >
            <el-table-column
              type="index"
              label="序号"
              width="65%"
            ></el-table-column>
            <el-table-column
              prop="code"
              label="股票代码"
              width="85%"
            ></el-table-column>
            <el-table-column
              prop="name"
              label="公司简称"
              width="85%"
            ></el-table-column>
            <el-table-column prop="industry" label="操作">
              <template #default="scope">
                <el-button
                  type="primary"
                  size="small"
                  @click="queryData(scope.row)"
                  >查询</el-button
                >
                <el-button
                  type="primary"
                  size="small"
                  @click="getData(scope.row)"
                  >获取</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </el-card>
        <el-card>
          <template #header>
            <div class="card-header">
              <span>{{ table_title }}</span>
            </div>
          </template>
          <el-table
            v-loading="loading"
            :data="stock_data"
            :show-header="true"
            :max-height="220"
            stripe
          >
            <el-table-column prop="record_date" label="时间"></el-table-column>
            <el-table-column prop="open_price" label="开盘价"></el-table-column>
            <el-table-column
              prop="close_price"
              label="收盘价"
            ></el-table-column>
            <el-table-column
              prop="volume"
              label="成交量(手)"
            ></el-table-column>
          </el-table>
        </el-card>
      </div>

      <div class="right-grid" ref="myChart"></div>
    </el-row>
  </div>
</template>

<script>
import axios from "axios";
import { ElMessage } from "element-plus";
import { getCurrentInstance } from "vue";
export default {
  data() {
    return {
      update_status: "未开始",
      loading: true,
      table_title: "个股数据",
      // 沪深300成分股数据
      table_data: [],
      // 个股详细数据
      stock_data: [],
      echarts: getCurrentInstance().appContext.config.globalProperties.$echarts,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      var url = "http://localhost:9001/queryAll";
      axios
        .get(url)
        .then((response) => {
          this.table_data = response.data;
          console.log(response);
          this.loading = false;
        })
        .catch((error) => {
          console.log(error);
          this.loading = false;
        });
    },
    // 绘制折线图
    create_axis() {
      //3.初始化实例对象 echarts.init(dom容器)
      var data_xAxis = [];
      var data_yAxis = [];
      for (var i = this.stock_data.length - 1; i >= 0; i--) {
        data_xAxis.push(this.stock_data[i].record_date);
        data_yAxis.push(this.stock_data[i].close_price);
      }
      console.log(data_xAxis);
      console.log(data_yAxis);
      var dom = this.$refs["myChart"]; // 获取dom节点
      var myChart = this.echarts.init(dom);
      //4.指定配置项和数据
      var option = {
        tooltip: {
          trigger: "axis",
          position: function (pt) {
            return [pt[0], "10%"];
          },
        },
        title: {
          left: "center",
          text: this.table_title,
        },
        toolbox: {
          feature: {
            dataZoom: {
              yAxisIndex: "none",
            },
            restore: {},
            saveAsImage: {},
          },
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: data_xAxis,
        },
        yAxis: {
          type: "value",
          boundaryGap: [0, "100%"],
        },
        dataZoom: [
          {
            type: "inside",
            start: 0,
            end: 10,
          },
          {
            start: 0,
            end: 10,
          },
        ],
        series: [
          {
            name: this.table_title,
            type: "line",
            symbol: "none",
            sampling: "lttb",
            itemStyle: {
              color: "rgb(135,206,235)",
            },
            areaStyle: {
              color: new this.echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "rgb(135,206,250)",
                },
                {
                  offset: 1,
                  color: "rgb(135,206,235)",
                },
              ]),
            },
            data: data_yAxis,
          },
        ],
      };
      //5.将配置项设置给echarts实例对象,使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    },
    // 查询数据
    queryData(row) {
      var url = "http://localhost:9001/stock/queryData/" + row.code;
      this.loading = true;
      this.table_title = row.code + " " + row.name;
      ElMessage("开始查询 " + this.table_title + " 的数据");
      axios
        .get(url)
        .then((response) => {
          this.stock_data = response.data;
          console.log(response);
          this.loading = false;
          ElMessage({
            message: "查询 " + this.table_title + " 的数据成功",
            type: "success",
          });
          // 绘制数据
          this.create_axis();
        })
        .catch((error) => {
          console.log(error);
          this.loading = false;
          ElMessage.error("查询 " + this.table_title + " 的数据失败");
        });
    },
    // 获取数据
    getData(row) {
      var url = "http://localhost:9001/stock/getData/" + row.code;
      this.loading = true;
      this.table_title = row.code + " " + row.name;
      ElMessage("开始获取 " + this.table_title + " 的数据");
      axios
        .get(url)
        .then((response) => {
          this.stock_data = response.data;
          console.log(response);
          this.loading = false;
          ElMessage({
            message: "获取 " + this.table_title + " 的数据成功",
            type: "success",
          });
          // 绘制数据
          this.create_axis();
        })
        .catch((error) => {
          console.log(error);
          this.loading = false;
          ElMessage.error("获取 " + this.table_title + " 的数据失败");
        });
    },
  },
};
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.container {
  display: grid;
  grid-template-columns: 35% 65%;
  width: 100%;
  height: 80vh;
}
.left-grid {
  background-color: #f0f0f0;
  border-radius: 2%;
  padding: 10px;
  height: 95%;
}
.right-grid {
  background-color: #f9ecc3;
  border-radius: 2%;
  padding: 10px;
  height: 95%;
}
</style>

前端页面有一个问题,就是数据量非常非常大,页面会很卡,这个问题的其中一个解决办法就是在获取数据的时候颗粒度可以小一点,比如一个星期获取一个数据之类的,因为一张图表也不可能展示出所有的数据,大家可能也只是想看一个总体的走势图,不过本文没有进行相关的优化,因为个人自用的话这点卡顿是可以接受的。 

结语

本文展示了通过网络爬虫获取个股详细数据,并且进行数据展示的方法,通过这个方法可以查询个股数据,并且用图表的方式将股票价格展示出来,这样可以非常直观地观察某一只股票的价格走势,由于获取到的数据量非常大,后期还可以进行一定的数据分析,如果你有什么想法欢迎和我交流,下面展示一下获取到的股票走势图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/280788.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ansible管理windows测试

一、环境介绍 Ansible管理主机&#xff1a; 系统: redhat7.6 Linux管理服务器需安装pywinrm插件 Windows客户端主机&#xff1a; 系统: Server2012R2 Windows机器需要安装或升级powershell4.0以上版本&#xff0c;Server2008R2默认的版本是2.0&#xff0c;因此必须升…

欢迎来到Web3.0的世界:Solidity智能合约安全漏洞分析

智能合约概述 智能合约是运行在区块链网络中的一段程序&#xff0c;经由多方机构自动执行预先设定的逻辑&#xff0c;程序执行后&#xff0c;网络上的最终状态将不可改变。智能合约本质上是传统合约的数字版本&#xff0c;由去中心化的计算机网络执行&#xff0c;而不是由政府…

Android Studio配置国内镜像源和HTTP代理/解决:Android Studio下载gradle速度慢的问题

&#xff08;方案一&#xff09;Android Studio配置国内镜像源和HTTP代理 一、配置国内镜像源/依赖库 1.1 打开项目的setting.gradle.kts文件 配置进去 pluginManagement {repositories {maven { urluri ("https://www.jitpack.io")}maven { urluri ("https:…

Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(一)

最近公司对大家的开发的硬件环境进行了升级&#xff0c;电脑主机的配置、显示器&#xff08;两台大屏显示器&#xff09;变得的逼格高多了。既然电脑上的开发环境都需要重装&#xff0c;就打算把开发环境也升级到最新版本&#xff0c;要用就用最新版本。下面对升级后的开发环境…

每日一题——LeetCode976

方法一 个人方法 找规律&#xff1a; 要求要围成三角形且周长最大&#xff0c;那么三条边自然是越大且越接近越好。那么我们就从最大的三条边开始看能不能围成三角形。如果不能组成三角形&#xff0c;则丢弃最长的那条&#xff0c;再取剩余边里最长的那条再看能不能组成三角形…

汽车制造厂批量使用成华制造弹簧平衡器

数年来&#xff0c;成华制造都在不断的向各行各界输出着自己的起重设备&#xff0c;与众多企业达成合作&#xff0c;不断供应优质产品。近些年&#xff0c;成华制造以其卓越的产品质量和高效的生产能力&#xff0c;成功实现了弹簧平衡器的大规模批量供应&#xff0c;为重庆数家…

R统计学1 - 基础操作入门问题1-20

R统计学入门基础问题 1. 如何生成100个高斯&#xff08;正态&#xff09;分布随机数 x <- rnorm(100, mean 5, sd 0.1) x # [1] 4.893534 5.046611 5.081097 4.979164 5.181700 5.038192 5.135376 5.173346 4.968877 4.986146 # [11] 4.946258 5.198199 5.055531 4.9430…

Git:远程仓库的使用

查看当前的远程库 要查看当前配置有哪些远程仓库&#xff0c;可以用git remote 命令&#xff0c;它会列出每个远程库的简短名字。在克隆完某个项目后&#xff0c;至少可以看到一个名为origin 的远程库&#xff0c;Git 默认使用这个名字来标识你所克隆的原始仓库&#xff1a; 也…

RHCE9学习指南 第13章 硬盘管理

新的硬盘首先需要对硬盘进行分区和格式化&#xff0c;首先了解一下硬盘的结构&#xff0c;如图13-1所示。 图13-1 磁盘上的磁道和扇区 硬盘的磁盘上有一个个的圈&#xff0c;每两个圈组成一个磁道。从中间往外发射线&#xff0c;把每个磁道分成一个个的扇区&#xff0c;每个扇…

QT上位机开发(第一个应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 不管是软件&#xff0c;还是硬件&#xff0c;如果我们能够顺利启动第一个应用&#xff0c;点亮第一个电路的话&#xff0c;这对我们的信心来说会有…

【MySQL】主从异步复制配置

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

Spring Boot快速搭建一个简易商城项目【完成登录功能且优化】

完成登录且优化&#xff1a; 未优化做简单的判断&#xff1a; 全部异常抓捕 优化&#xff1a;返回的是json的格式 BusinessException&#xff1a;所有的错误放到这个容器中&#xff0c;全局异常从这个类中调用 BusinessException&#xff1a; package com.lya.lyaspshop.exce…

unity学习笔记----游戏练习03

一、修复植物种植的问题 1.当手上存在植物时&#xff0c;再次点击卡片上的植物就会在手上添加新的植物&#xff0c;需要修改成只有手上没有植物时才能再次获取到植物。需要修改AddPlant方法。 public bool AddPlant(PlantType plantType) { //防止手上出现多个植…

《深入理解C++11:C++11新特性解析与应用》笔记五

第五章 提高类型安全 5.1 强类型枚举 5.1.1 枚举&#xff1a;分门别类与数值的名字 具名枚举类型一般声明类似&#xff1a;enum Gender { Male, Female }。 匿名枚举类型可以使用三种方式实现&#xff1a; 第一种方式时宏&#xff0c;比如 #define Male 0 #define Femal…

安全生产知识竞赛活动方案

为进一步普及安全生产法律法规知识&#xff0c;增强安全意识&#xff0c;提高安全技能&#xff0c;经研究&#xff0c;决定举办以“加强安全法治、保障安全生产”为主题的新修订《安全生产法》知识竞赛活动&#xff0c;现将有关事项通知如下&#xff1a; 一、活动时间&#xf…

机器学习(二) -- 数据预处理(3)

系列文章目录 机器学习&#xff08;一&#xff09; -- 概述 机器学习&#xff08;二&#xff09; -- 数据预处理&#xff08;1-3&#xff09; 未完待续…… 目录 前言 tips&#xff1a;这里只是总结&#xff0c;不是教程哈。本章开始会用到numpy&#xff0c;pandas以及matpl…

【Kubernetes】什么是 kubectl ?

什么是 kubectl &#xff1f; 1.什么是 kubectl &#xff1f;2.Kubernetes 内部结构3.Kubernetes API 的作用 1.什么是 kubectl &#xff1f; 在学习如何更有效地使用 kubectl 之前&#xff0c;您应该对它是什么以及它如何工作有一个基本的了解。从用户的角度来看&#xff0c;…

助力打造智慧数字课堂,基于YOLOv8全系列【n/s/m/l/x】不同参数量级模型开发构建教学课堂场景下学生课堂行为检测识别分析系统

近年来&#xff0c;随着行为检测技术的发展&#xff0c;分析学生在课堂视频中的行为&#xff0c;以获取他们的课堂状态和学习表现信息已经成为可能。这项技术对学校的教师、管理人员、学生和家长都非常重要。使用深度学习方法自动检测学生的课堂行为是分析学生课堂表现和提高教…

计算机视觉技术-目标检测数据集

目标检测领域没有像MNIST和Fashion-MNIST那样的小数据集。 为了快速测试目标检测模型&#xff0c;我们收集并标记了一个小型数据集。 首先&#xff0c;我们拍摄了一组香蕉的照片&#xff0c;并生成了1000张不同角度和大小的香蕉图像。 然后&#xff0c;我们在一些背景图片的随机…

分享好用稳定快递查询api接口(对接简单)

提供实时查询和自动识别单号信息。稳定高效&#xff0c;调用简单方便&#xff0c;性价比高&#xff0c;一条链接即可对接成功。 使用数据平台该API接口需要先注册后申请此API接口。申请成功后赠送免费次数&#xff0c;可直接在线请求接口数据。 接口地址&#xff1a;https://…