SpringBoot项目——使用Spark对爬虫爬取下的数据进行清洗
随着互联网信息呈爆炸式增长,爬虫技术被广泛用于从海量网页中抓取有价值的数据。然而,爬取到的数据往往存在格式不规范、重复、噪声等诸多问题,需要高效的数据清洗流程来保障数据质量,Spark 在其中发挥了关键作用。
什么是Spark
Spark 是当今大数据领域最活跃、最热门、最高效的大数据通用计算平台之一。
Spark 是为大规模数据处理而设计的分布式计算框架,旨在处理海量数据的存储和分析任务。它可以在集群环境中运行,将计算任务分布到多个节点上,利用集群的并行处理能力来加速数据处理过程。提供了基础的弹性分布式数据集(RDD)抽象,是 Spark 的核心部分,可进行通用的分布式数据处理操作。
Spark的优点
- 快:与Hadoop的MapReduce相比,Spark基于内存的运算要快100倍以上;而基于磁盘的运算也要快10倍以上。Spark实现了高效的DAG执行引擎,可以通过基于内存来高效地处理数据流。
- 易用:Spark支持Java、Python和Scala的API,还支持超过80种高级算法,使用户可以快速构建不同应用。而且Spark支持交互式的Python和Scala的Shell,这意味着可以非常方便的在这些Shell中使用Spark集群来验证解决问题的方法,而不是像以前一样,需要打包、上传集群、验证等。这对于原型开发非常重要。
- 通用性:Spark提供了统一的解决方案。Spark可以用于批处理、交互式查询(通用Spark SQL)、实时流处理(通过Spark Streaming)、机器学习(通过Spark MLlib)和图计算(通过Spark GraphX)。这些不同类型的处理都可以在同一应用中无缝使用。Spark统一的解决方案非常具有吸引力,毕竟任何公司都想用统一的平台处理问题,减少开发和维护的人力成本和部署平台的物理成本。当然还有,作为统一的解决方案,Spark并没有以牺牲性能为代价。相反,在性能方面Spark具有巨大优势。
- 可融合性:Spark非常方便的与其他开源产品进行融合。比如,Spark可以使用Hadoop的YARN和Apache Mesos作为它的资源管理和调度器,并且可以处理所有Hadoop支持的数据,包括HDFS、HBase和Cassanda等。这对于已部署Hadoop集群的用户特别重要,因为不需要做任何数据迁移就可以使用Spark强大的处理能力。Spark也可以不依赖第三方的资源管理器和调度器,它实现了Standalone作为其内置资源管理器和调度框架,这样进一步降低了Spark的使用门槛,使得所有人可以非常容易地部署和使用Spark。此外Spark还提供了在EC2上部署Standalone的Spark集群的工具。
Spark的使用
Spark大至使用流程
- 要先将数据进行存放在一个txt文本文件当中,
- 使用Spark进行读取txt中的文本数据,进行数据处理
- 将清洗后的数据转存到原来的txt文件当中
- 想要存放到数据库当中,则将txt文本文件中的数据再次读出出来存放进去即可
Spark的maven依赖
Spark想要在Springboot项目中使用要引入相应的maven依赖
<dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.4.1</version>
</dependency>
<dependency><groupId>org.apache.spark</groupId><artifactId>spark-sql_2.12</artifactId><version>3.4.1</version>
</dependency>
爬取出数据的存储
本项目进行爬取的是求职网站,会将求职岗位的信息放入到一个List集合当中,通过遍历这个List集合,将数据存放到txt文本中
/*** @param jobs 爬取下来的数据集合* @param filePath 你要存放数据的地址*/public static void writeDataToTxt(List<Job> jobs, String filePath) {//进行检查文件是否存在 若不存在则进行创建一个路径为filePath的文件File file = new File(filePath);if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {throw new RuntimeException(e);}}try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {// 将数据写入文件for(Job job : jobs) {//这里因为直接进行放入到txt文本文件难以进行格式处理 我们使用手动进行拼接操作String j = job.getJobName()+","+job.getCompany()+","+job.getSalary()+","+job.getExperience()+","+job.getEducational()+","+job.getCity()+","+job.getCompanyScale()+","+job.getCompanyStatus();writer.write(j);// 写入换行符writer.newLine();}} catch (IOException e) {// 处理可能出现的异常System.err.println("写入文件时出现错误: " + e.getMessage());}}
Spark的数据清洗
本项目中的Spark进行数据清洗是通过JavaRDD<E>
JavaRDD 是 Spark 为 Java 开发者提供的弹性分布式数据集(Resilient Distributed Dataset,RDD)接口。从本质上讲,它是一个分布式的集合,其中的数据被划分成多个分区(Partitions),这些分区可以分布在集群中的不同节点上进行并行处理。这种分布式的特性使得 JavaRDD 能够高效地处理大规模的数据。
JavaRDD 是 Spark Core 的重要组成部分,是构建其他高级功能(如 Spark SQL、MLlib 和 Spark Streaming)的基础。在 Spark SQL 中,数据通常被封装成 DataFrame 或 Dataset,但这些高级数据结构的底层实现往往也依赖于 RDD 的基本概念和操作。
JavaRDD 可以存储各种类型的数据,包括 Java 基本数据类型(如int
、double
、boolean
等)和自定义的 Java 对象。
使用JavaRDD 的filter方法和map方法进行对数据的处理
- filter 方法是用来对流中的元素进行筛选的,它的返回值应该是一个 boolean 类型的表达式,用来判断该元素是否应该保留在流中
- map 方法是一种转换操作,它对 JavaRDD 中的每个元素应用一个函数,并返回一个新的 JavaRDD
/*** @param path 要进行清洗的txt文件路径*/public static void DataClening(String path){SparkSession spark = SparkSession.builder()//将 SparkContext、SQLContext 和 HiveContext 等功能集成在一起.appName("Java Spark")//为 Spark 应用程序设置一个名称 名称会显示在 Spark 集群的监控界面上,有助于识别和管理应用程序.master("local[*]")//表示在本地运行 Spark.getOrCreate();//尝试获取现有的 SparkSession 实例,如果不存在则创建一个新的。这样可以确保在同一个 JVM 中不会创建多个 SparkSession,避免资源浪费JavaSparkContext sc = JavaSparkContext.fromSparkContext(spark.sparkContext());//读取数据源到RDD中JavaRDD<String> rdd = sc.textFile(path);//对RDD中的数据进行清洗处理JavaRDD<String> cleanedData = cleanData(rdd);// 打印清洗后的数据(可以根据需要保存到文件或进行其他操作) 此处不要省略 不然会报错cleanedData.collect().forEach(System.out::println);//进行检查文件是否存在File file = new File(path);if (file.exists()) {file.delete();}try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) {// 将数据写入文件for(String job : cleanedData.collect()) {writer.write(job);// 写入换行符writer.newLine();}} catch (IOException e) {// 处理可能出现的异常System.err.println("清洗数据后写入文件时出现错误: " + e.getMessage());}// 停止Spark上下文sc.stop();}/*** 对数据进行清洗操作* @param rawData 需要进行清洗的JavaRDD对象* @return 返回进行清洗的JavaRDD对象*/private static JavaRDD<String> cleanData(JavaRDD<String> rawData) {return rawData//filter 方法是用来对流中的元素进行筛选的,它的返回值应该是一个 boolean 类型的表达式,用来判断该元素是否应该保留在流中// 移除空行.filter(line -> !line.trim().isEmpty())// 例如,移除含有特定字符(如null)的行//.filter(line -> !line.contains("null"))// map 是一种转换操作,它对 JavaRDD 中的每个元素应用一个函数,并返回一个新的 JavaRDD// 可能需要根据分隔符(例如逗号)拆分字段并重新格式化.map(line -> {String[] fields = line.replace("null", "暂无数据信息").split(",");//进行数据检查 确保这工作名称等8项信息完整 不完整直接进行设置为空if (fields.length == 8) {//将fields字符串数组中的信息进行拼接起来 这里仅做简单拼接为清洗后的格式,实际清洗可以根据需求更复杂return String.join(",", fields);} else {return ""; //将不满足8项信息的数据进行设置为空处理}})// 去除清洗后的空行或不需要的数据.filter(line -> !line.trim().isEmpty())//去重.distinct();}
清洗后数据存放
此处会将txt文件中的数据进行取出,放入到一个List集合当中,想要放入到数据库中,只需要进行遍历这个集合即可
/*** * @param path 将指定位置的txt文件中的信息 放入到List集合中 便于插入到数据库中* @return 返回文本中的·数据信息*/public static List<Job> getJobbyTxtFile(String path){List<Job> jobs = new ArrayList<>();try (BufferedReader reader = new BufferedReader(new FileReader(path))) {String line;while ((line = reader.readLine())!= null) {jobs.add(toJob(line));}} catch (IOException e) {e.printStackTrace();}return jobs;}public static Job toJob(String job){String[] jobsContext = job.split(",");Job j = new Job();j.setJobName(jobsContext[0]);j.setCompany(jobsContext[1]);j.setSalary(jobsContext[2]);j.setExperience(jobsContext[3]);j.setEducational(jobsContext[4]);j.setCity(jobsContext[5]);j.setCompanyScale(jobsContext[6]);j.setCompanyStatus(jobsContext[7]);return j;}
相关文章:
SpringBoot项目——使用Spark对爬虫爬取下的数据进行清洗
随着互联网信息呈爆炸式增长,爬虫技术被广泛用于从海量网页中抓取有价值的数据。然而,爬取到的数据往往存在格式不规范、重复、噪声等诸多问题,需要高效的数据清洗流程来保障数据质量,Spark 在其中发挥了关键作用。 什么是Spark …...
分布式锁 Redis vs etcd
为什么要实现分布式锁?为什么需要分布式锁,分布式锁的作用是什么,哪些场景会使用到分布式锁?分布式锁的实现方式有哪些分布式锁的核心原理是什么 如何实现分布式锁redis(自旋锁版本)etcd 的分布式锁(互斥锁(信号控制)版本) 分布式锁对比redis vs etcd 总结 为什么要实现分布式…...
《深度剖析:开源与闭源模型,AI舞台上的不同角色》
在人工智能蓬勃发展的当下,模型的选择如同为一场战役挑选合适的武器,至关重要。开源模型与闭源模型作为AI领域的两大阵营,在性能和应用场景上展现出显著差异,深刻影响着开发者、企业以及整个行业的走向。 性能差异:实…...
Angular结合C#
在 Angular 2 及以上版本与 C#结合使用 REST API 的示例中,我们将分别展示前端 Angular 服务和后端 C# Web API 的实现。 一、前端:Angular 服务 生成 Angular 服务 使用 Angular CLI 生成一个新的服务,例如user.service.ts: ng…...

Spring——自动装配
假设一个场景: 一个人(Person)有一条狗(Dog)和一只猫(Cat),狗和猫都会叫,狗叫是“汪汪”,猫叫是“喵喵”,同时人还有一个自己的名字。 将上述场景 抽象出三个实体类&…...
Servlet与JSP:Java的秘密花园入口
1 Servlet概述 Servlet是Java Web应用中的一个核心组件,它是一个运行在服务器端的Java程序,可以响应客户端的请求并生成响应。Servlet为Web应用提供了一个统一的接口来处理HTTP请求。 2 Servlet的生命周期 Servlet的生命周期包括以下几个阶段ÿ…...

【Linux】Linux常见指令(上)
个人主页~ 初识Linux 一、Linux基本命令1、ls指令2、pwd命令3、cd指令4、touch指令5、mkdir指令6、rmdir指令7、rm指令8、man指令9、cp指令10、mv命令 Linux是一个开源的、稳定的、安全的、灵活的操作系统,Linux下的操作都是通过指令来实现的 一、Linux基本命令 先…...

ELFK日志采集实战
一、日志分析概述 日志分析是运维工程师解决系统故障,发现问题的主要手段 日志主要包括系统日志、应用程序日志和安全日志 系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因 经常分析日志可以了解服务器的负荷&#x…...
Kubernetes 使用自定义资源(CRD)扩展API
K8s CRD 即 Kubernetes CustomResourceDefinition,是 Kubernetes 提供的一种扩展机制,允许用户在 Kubernetes 集群中定义和使用自定义的资源类型。通过定义 CRD,用户可以在 Kubernetes 集群中创建、读取、更新和删除自定义资源对象࿰…...

用户使用LLM模型都在干什么?
Anthropic 对用户与 Claude 3.5 Sonnet 的大量匿名对话展开分析,主要发现及相关情况如下: 使用用途分布 软件开发主导:在各类使用场景中,软件开发占比最高,其中编码占 Claude 对话的 15% - 25%,网页和移动应…...
MySQL常用命令之汇总(Summary of Commonly Used Commands in MySQL)
MySQL常用命令汇总 简介 MySQL是一个广泛使用的开源关系型数据库管理系统,由瑞典的MySQL AB公司开发,现属于Oracle公司。 MySQL支持SQL(结构化查询语言),这是数据库操作的标准语言,用户可以使用SQL进…...
六年之约day10
今日开心∶今天部门开了个颁奖大会,看着别人收获的荣誉,还真有些羡慕,什么时候,我也能拥有属于自己的荣誉啊. 今日不开心∶活没干多少,对业务也不是很懂 今日思考∶很多事情,存在即合理.工作,…...

springboot和vue配置https请求
项目场景: 代码发布到线上使用https请求需要配置ssl证书,前后端都需要修改。 问题描述 如图,我们在调用接口时报如下错误,这就是未配置ssl但是用https请求产生的问题。 解决方案: 前端:在vite.config.js文…...

selenium遇见伪元素该如何处理?
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 问题发生 在很多前端页面中,大家会见到很多::before、::after 元素,比如【百度流量研究院】: 比如【百度疫情大数…...

慧集通(DataLinkX)iPaaS集成平台-数据质量
1.什么是数据质量 介绍: 数据质量的主要作用就是记录组件写入的数据,及执行时的相关信息,如执行的最终状态(成功,失败,进行中等),执行的时间(创建时间,修改时…...

微软发布AIOpsLab:一个开源的全面AI框架,用于AIOps代理
在当今这个云计算技术迅猛发展的时代,企业面临着前所未有的挑战与机遇。随着云基础设施的日益复杂化,它们成为了企业运营不可或缺的支柱。网站可靠性工程师(Site Reliability Engineers,简称SRE)和DevOps团队肩负着关键…...

ElasticSearch | Elasticsearch与Kibana页面查询语句实践
关注:CodingTechWork 引言 在当今大数据应用中,Elasticsearch(简称 ES)以其高效的全文检索、分布式处理能力和灵活的查询语法,广泛应用于各类日志分析、用户行为分析以及实时数据查询等场景。通过 ES,用户…...
12.C语言中的struct详解:定义、赋值、指针、嵌套与位字段
目录 1.简介2.struct 的复制3.struct 指针4.struct 的嵌套5.位字段6.弹性数组成员 1.简介 本篇原文为:C语言中的struct详解:定义、赋值、指针、嵌套与位字段。 更多C进阶、rust、python、逆向等等教程,可点击此链接查看:酷程网 …...
文件读写到SQLite数据库的方法
在 SQLite 数据库中,将文件读写到数据库的常见方法主要有以下几种: 1. 将文件以 BLOB 类型存储 BLOB(Binary Large Object) 是 SQLite 中的二进制数据类型,可以直接用来存储文件内容。 步骤: 创建表 创建一…...

springboot项目部署至linux
1.修改pom.xml 确认是否有以下代码,没有请进行添加,mainClass改成你的启动类 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.ve…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...