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…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
