《花100块做个摸鱼小网站! 》第五篇—通过xxl-job定时获取热搜数据

2024-09-03 03:20

本文主要是介绍《花100块做个摸鱼小网站! 》第五篇—通过xxl-job定时获取热搜数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

⭐️基础链接导航⭐️

服务器 → ☁️ 阿里云活动地址

看样例 → 🐟 摸鱼小网站地址

学代码 → 💻 源码库地址

一、前言

我们已经成功实现了一个完整的热搜组件,从后端到前端,构建了这个小网站的核心功能。接下来,我们将不断完善其功能,使其更加美观和实用。今天的主题是如何定时获取热搜数据。如果热搜数据无法定时更新,小网站将失去其核心价值。之前,我采用了@Scheduled注解来实现定时任务,但这种方式灵活性不足,因此我决定用更灵活的XXL-Job组件来替代它。

二、xxl-job部署

xxl-job是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。目前github代码库star 27.3k,开源免费的,值得学习使用一下。

1. 代码库下载

github代码库地址

下载下来后,代码库结构如下:

源码结构如下:

xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器):xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;:xxl-job-executor-sample-frameless:无框架版本;

调度中心配置内容说明:

### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver### 报警邮箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory### 调度中心通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文;
xxl.job.i18n=zh_CN## 调度线程池最大线程配置【必填】
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
xxl.job.logretentiondays=30

2. 表结构初始化

在doc目录的 db目录下,有一个sql文件,里面有一些表和数据的初始化sql,我们要在执行XXL-Job之前要把表和数据准备好。

执行结束后,表如下:

3. 启动XXL-Job

找到XxlJobAdminApplication,启动该应用,在浏览器输入:http://localhost:12000/xxl-job-admin/toLogin,会进入XXL-Job登录界面,如下:

输入用户名:admin;密码:123456点击登录进入主界面,如下:

三、自定义爬虫任务

XXL-Job的使用也很简单,一个注解就好了,这里我说一下如何使用它。

1. 引入XXL-Job依赖

summo-sbmy-job的pom.xml下添加:

<!-- xxl-job -->
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.1</version>
</dependency>

2. XXL-Job配置

在application.preoperties文件中加入XXL-Job的配置,配置如下:

# xxl-job
xxl.job.open=true
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:12000/xxl-job-admin
### xxl-job, access token
xxl.job.accessToken=default_token
### xxl-job executor appname
xxl.job.executor.appname=summo-sbmy
### xxl-job executor log-path
xxl.job.executor.logpath=/root/logs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=
xxl.job.executor.port=9999

配置弄好之后,在com.summo.sbmy.job.config目录下创建一个config文件,创建XxlJobConfig.java,代码如下:

package com.summo.sbmy.job.config;import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** xxl-job config** @author xuxueli 2017-04-28*/
@Configuration
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.appname}")private String appname;@Value("${xxl.job.executor.address}")private String address;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Bean@ConditionalOnProperty(name = "xxl.job.open", havingValue = "true")public XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}
}

配置和类都弄好之后,重新启动应用,如果顺利的话,在XXL-Job管理的执行器界面上就可以看到一个执行器已经注册了,如下:

4. 注册XXL-Job任务

以抖音热搜为例,我们最开始使用的是 @Scheduled注解,代码如下:

/*** 定时触发爬虫方法,1个小时执行一次*/
@Scheduled(fixedRate = 1000 * 60 * 60)
public void hotSearch() throws IOException{... ...
}

@Scheduled注解替换为@XxlJob("douyinHotSearchJob"),具体的代码如下:

package com.summo.sbmy.job.douyin;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.summo.sbmy.dao.entity.SbmyHotSearchDO;
import com.summo.sbmy.service.SbmyHotSearchService;
import com.summo.sbmy.service.convert.HotSearchConvert;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.stream.Collectors;import static com.summo.sbmy.common.cache.SbmyHotSearchCache.CACHE_MAP;
import static com.summo.sbmy.common.enums.HotSearchEnum.DOUYIN;/*** @author summo* @version DouyinHotSearchJob.java, 1.0.0* @description 抖音热搜Java爬虫代码* @date 2024年08月09*/
@Component
@Slf4j
public class DouyinHotSearchJob {@Autowiredprivate SbmyHotSearchService sbmyHotSearchService;@XxlJob("douyinHotSearchJob")public ReturnT<String> hotSearch(String param) throws IOException {log.info("抖音热搜爬虫任务开始");try {//查询抖音热搜数据OkHttpClient client = new OkHttpClient().newBuilder().build();Request request = new Request.Builder().url("https://www.iesdouyin.com/web/api/v2/hotsearch/billboard/word/").method("GET", null).build();Response response = client.newCall(request).execute();JSONObject jsonObject = JSONObject.parseObject(response.body().string());JSONArray array = jsonObject.getJSONArray("word_list");List<SbmyHotSearchDO> sbmyHotSearchDOList = Lists.newArrayList();for (int i = 0, len = array.size(); i < len; i++) {//获取知乎热搜信息JSONObject object = (JSONObject) array.get(i);//构建热搜信息榜SbmyHotSearchDO sbmyHotSearchDO = SbmyHotSearchDO.builder().hotSearchResource(DOUYIN.getCode()).build();//设置文章标题sbmyHotSearchDO.setHotSearchTitle(object.getString("word"));//设置知乎三方IDsbmyHotSearchDO.setHotSearchId(getHashId(DOUYIN.getCode() + sbmyHotSearchDO.getHotSearchTitle()));//设置文章连接sbmyHotSearchDO.setHotSearchUrl("https://www.douyin.com/search/" + sbmyHotSearchDO.getHotSearchTitle() + "?type=general");//设置热搜热度sbmyHotSearchDO.setHotSearchHeat(object.getString("hot_value"));//按顺序排名sbmyHotSearchDO.setHotSearchOrder(i + 1);sbmyHotSearchDOList.add(sbmyHotSearchDO);}if (CollectionUtils.isEmpty(sbmyHotSearchDOList)) {return ReturnT.SUCCESS;}//数据加到缓存中CACHE_MAP.put(DOUYIN.getCode(), sbmyHotSearchDOList.stream().map(HotSearchConvert::toDTOWhenQuery).collect(Collectors.toList()));//数据持久化sbmyHotSearchService.saveCache2DB(sbmyHotSearchDOList);log.info("抖音热搜爬虫任务结束");} catch (IOException e) {log.error("获取抖音数据异常", e);}return ReturnT.SUCCESS;}/*** 根据文章标题获取一个唯一ID** @param title 文章标题* @return 唯一ID*/private String getHashId(String title) {long seed = title.hashCode();Random rnd = new Random(seed);return new UUID(rnd.nextLong(), rnd.nextLong()).toString();}}

在XXL-Job管理台的任务管理界面中点击新增任务,如下:

创建好任务后,我们可以手动运行一次,如下:

这样抖音的热搜任务我们就配置好了,其他的爬虫任务也是这样的配置。

四、热搜更新时间

目前我们已经实现了三个热搜组件,百度、抖音、知乎,但是我们并不知道这些热搜是什么时候更新的,也不知道是不是实时的,所以我们需要把热搜更新时间放出来,大概下面这样子:


优化后组件代码如下:

<template><el-card class="custom-card" v-loading="loading"><template #header><div class="card-title"><img :src="icon" class="card-title-icon" />{{ title }}热榜<span class="update-time">{{ formattedUpdateTime }}</span></div></template><div class="cell-group-scrollable"><divv-for="item in hotSearchData":key="item.hotSearchOrder":class="getRankingClass(item.hotSearchOrder)"class="cell-wrapper"><span class="cell-order">{{ item.hotSearchOrder }}</span><spanclass="cell-title hover-effect"@click="openLink(item.hotSearchUrl)">{{ item.hotSearchTitle }}</span><span class="cell-heat">{{ formatHeat(item.hotSearchHeat) }}</span></div></div></el-card>
</template><script>
import apiService from "@/config/apiService.js";export default {props: {title: String,icon: String,type: String,},data() {return {hotSearchData: [],updateTime: null,loading: false,};},created() {this.fetchData(this.type);},computed: {formattedUpdateTime() {if (!this.updateTime) return '';const updateDate = new Date(this.updateTime);const now = new Date();const timeDiff = now - updateDate;const minutesDiff = Math.floor(timeDiff / 1000 / 60);if (minutesDiff < 1) {return '刚刚更新';} else if (minutesDiff < 60) {return `${minutesDiff}分钟前更新`;} else if (minutesDiff < 1440) {return `${Math.floor(minutesDiff / 60)}小时前更新`;} else {return updateDate.toLocaleString();}},},methods: {fetchData(type) {this.loading = true;apiService.get("/hotSearch/queryByType?type=" + type).then((res) => {this.hotSearchData = res.data.data.hotSearchDTOList;this.updateTime = res.data.data.updateTime;}).catch((error) => {console.error(error);}).finally(() => {this.loading = false; });},getRankingClass(order) {if (order === 1) return "top-ranking-1";if (order === 2) return "top-ranking-2";if (order === 3) return "top-ranking-3";return "";},formatHeat(heat) {if (typeof heat === "string" && heat.endsWith("万")) {return heat;}let number = parseFloat(heat);if (isNaN(number)) {return heat;}if (number < 1000) {return number.toString();}if (number >= 1000 && number < 10000) {return (number / 1000).toFixed(1) + "k";}if (number >= 10000) {return (number / 10000).toFixed(1) + "万";}},openLink(url) {if (url) {window.open(url, "_blank");}},},
};
</script><style scoped>
.custom-card {background-color: #ffffff;border-radius: 10px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);margin-bottom: 20px;
}
.custom-card:hover {box-shadow: 0 6px 8px rgba(0, 0, 0, 0.25);
}
.el-card__header {padding: 10px 18px;display: flex;justify-content: space-between; /* Added to space out title and update time */align-items: center;
}
.card-title {display: flex;align-items: center;font-weight: bold;font-size: 16px;flex-grow: 1;
}
.card-title-icon {fill: currentColor;width: 24px;height: 24px;margin-right: 8px;
}
.update-time {font-size: 12px;color: #b7b3b3;margin-left: auto; /* Ensures it is pushed to the far right */
}
.cell-group-scrollable {max-height: 350px;overflow-y: auto;padding-right: 16px; flex: 1;
}
.cell-wrapper {display: flex;align-items: center;padding: 8px 8px; border-bottom: 1px solid #e8e8e8; 
}
.cell-order {width: 20px;text-align: left;font-size: 16px;font-weight: 700;margin-right: 8px;color: #7a7a7a; 
}
.cell-heat {min-width: 50px;text-align: right;font-size: 12px;color: #7a7a7a;
}
.cell-title {font-size: 13px;color: #495060;line-height: 22px;flex-grow: 1;overflow: hidden;text-align: left; text-overflow: ellipsis; 
}
.top-ranking-1 .cell-order {color: #fadb14; /* 金色 */
}
.top-ranking-2 .cell-order {color: #a9a9a9; /* 银色 */
}
.top-ranking-3 .cell-order {color: #d48806; /* 铜色 */
}
.cell-title.hover-effect {cursor: pointer; transition: color 0.3s ease; 
}
.cell-title.hover-effect:hover {color: #409eff; 
}
</style>

优化后,我们看一下最终的样式,如下:

这样,我们使用XXL-Job改造热搜组件就完成了,详细代码可以去看我的代码仓库。

番外:B站热搜爬虫

1. 爬虫方案评估

B站不是热搜,是热门视频, 但逻辑是一样的,它的接口是:https://api.bilibili.com/x/web-interface/ranking/v2

这个接口返回的是JSON格式数据,这就很简单了,看下结构就行。

2. 网页解析代码

这个就可以使用Postman生成调用代码,流程我就不赘述了,直接上代码,BilibiliHotSearchJob:

package com.summo.sbmy.job.bilibili;import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;import com.google.common.collect.Lists;
import com.summo.sbmy.common.model.dto.HotSearchDetailDTO;
import com.summo.sbmy.dao.entity.SbmyHotSearchDO;
import com.summo.sbmy.service.SbmyHotSearchService;
import com.summo.sbmy.service.convert.HotSearchConvert;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import static com.summo.sbmy.common.cache.SbmyHotSearchCache.CACHE_MAP;
import static com.summo.sbmy.common.enums.HotSearchEnum.BILIBILI;/*** @author summo* @version BilibiliHotSearchJob.java, 1.0.0* @description B站热榜Java爬虫代码* @date 2024年08月19*/
@Component
@Slf4j
public class BilibiliHotSearchJob {@Autowiredprivate SbmyHotSearchService sbmyHotSearchService;@XxlJob("bilibiliHotSearchJob")public ReturnT<String> hotSearch(String param) throws IOException {log.info("B站热搜爬虫任务开始");try {//查询B站热搜数据OkHttpClient client = new OkHttpClient().newBuilder().build();Request request = new Request.Builder().url("https://api.bilibili.com/x/web-interface/ranking/v2").addHeader("User-Agent", "Mozilla/5.0 (compatible)").addHeader("Cookie", "b_nut=1712137652; "+ "buvid3=DBA9C433-8738-DD67-DCF5" + "-DDC780CA892052512infoc").method("GET", null).build();Response response = client.newCall(request).execute();JSONObject jsonObject = JSONObject.parseObject(response.body().string());JSONArray array = jsonObject.getJSONObject("data").getJSONArray("list");List<SbmyHotSearchDO> sbmyHotSearchDOList = Lists.newArrayList();for (int i = 0, len = array.size(); i < len; i++) {//获取B站热搜信息JSONObject object = (JSONObject)array.get(i);//构建热搜信息榜SbmyHotSearchDO sbmyHotSearchDO = SbmyHotSearchDO.builder().hotSearchResource(BILIBILI.getCode()).build();//设置B站三方IDsbmyHotSearchDO.setHotSearchId(object.getString("aid"));//设置文章连接sbmyHotSearchDO.setHotSearchUrl(object.getString("short_link_v2"));//设置文章标题sbmyHotSearchDO.setHotSearchTitle(object.getString("title"));//设置作者名称sbmyHotSearchDO.setHotSearchAuthor(object.getJSONObject("owner").getString("name"));//设置作者头像sbmyHotSearchDO.setHotSearchAuthorAvatar(object.getJSONObject("owner").getString("face"));//设置文章封面sbmyHotSearchDO.setHotSearchCover(object.getString("pic"));//设置热搜热度sbmyHotSearchDO.setHotSearchHeat(object.getJSONObject("stat").getString("view"));//按顺序排名sbmyHotSearchDO.setHotSearchOrder(i + 1);sbmyHotSearchDOList.add(sbmyHotSearchDO);}if (CollectionUtils.isEmpty(sbmyHotSearchDOList)) {return ReturnT.SUCCESS;}//数据加到缓存中CACHE_MAP.put(BILIBILI.getCode(), HotSearchDetailDTO.builder()//热搜数据.hotSearchDTOList(sbmyHotSearchDOList.stream().map(HotSearchConvert::toDTOWhenQuery).collect(Collectors.toList()))//更新时间.updateTime(Calendar.getInstance().getTime()).build());//数据持久化sbmyHotSearchService.saveCache2DB(sbmyHotSearchDOList);log.info("B站热搜爬虫任务结束");} catch (IOException e) {log.error("获取B站数据异常", e);}return ReturnT.SUCCESS;}}

看下效果,第一行的4个热搜已经出来了,如下:

这篇关于《花100块做个摸鱼小网站! 》第五篇—通过xxl-job定时获取热搜数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131876

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav