手机网站怎么制作软件,长沙网站托管seo优化公司,陕西渭南住房和城乡建设厅网站,企业系统申报目录 前言
一、数据转换
1、Json转JavaBean
2、JavaBean与数据库字段映射
二、空间数据表设计
1、表结构设计
三、PostGIS数据保存
1、Mapper接口定义
2、Service逻辑层实现
3、数据入库
4、运行实例及结果
总结 前言 在上一篇博客中基于Java的XxlCrawler网络信息爬…目录 前言
一、数据转换
1、Json转JavaBean
2、JavaBean与数据库字段映射
二、空间数据表设计
1、表结构设计
三、PostGIS数据保存
1、Mapper接口定义
2、Service逻辑层实现
3、数据入库
4、运行实例及结果
总结 前言 在上一篇博客中基于Java的XxlCrawler网络信息爬取实战-以中国地震台网为例我们使用Java语言采用XxlCrawer组件进行中国地震台网数据的爬取相信大家对如何抓取这种接口数据一定有了基本的认识也掌握了如何基于XxlCrawer来实现自己的信息爬取实战。但是在前面的博客当中我们仅仅是将信息爬取下来。为了在我们自己的应用系统中来应用这些基础数据需要我们将爬取的数据进行存储起来。由于地震数据包含了空间位置信息为方便进行空间分析的实现。这里我们将爬取的中国地震信息存储到PostGIS空间数据库中为下一步的数据分析和可视化呈现奠定良好的基础。 本文即紧紧围绕着将信息保存到空间数据库的目标重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。如果您当前也有对地震等地质灾害数据进行分析的需求不妨看看本博文。
一、数据转换 在前面的博客中有提到在中国地震台网中展示接口数据将请求数据在浏览器中进行查看。可以看到以下的格式 通过这个接口可以看到官方返回的数据中其所有的字段名都是大写的如下所示
AUTO_FLAG: M
CATA_ID: CD20240413222636.00
CATA_TYPE:
EPI_DEPTH: 9
EPI_LAT: 24.05
EPI_LON: 121.60
EQ_CATA_TYPE:
EQ_TYPE: M
IS_DEL:
LOCATION_C: 台湾花莲县
LOCATION_S:
LOC_STN: 0
M: 4.2
M_MB: 0
M_MB2: 0
M_ML: 0
M_MS: 0
M_MS7: 0
NEW_DID: CD20240413222636
O_TIME: 2024-04-13 22:26:35
O_TIME_FRA: 0
SAVE_TIME: 2024-04-13 22:35:56
SUM_STN: 0
SYNC_TIME: 2024-04-13 22:35:56
id: 46396 为了让更好的使用Java语言进行开发使这些变量名变得更加合适同时满足Java的编程规范。因此办结来重点讲解怎么将 json返回的数据转成java的合理变量名。
1、Json转JavaBean 如上所言在使用XxlCrawler进行信息爬取之后返回的数据名称不太符合Java的命名规则。那针对这种需求有没有什么办法来进行调整呢。答案是肯定的不管是用Gson或者fastJson这些设计良好的json处理框架其实都包含了Json对象与JavaBean对象的互相转换。当给定格式不符合Java命名规范的属性名可以通过注解映射的方式修改成符合Java编码规范的变量。由于本实例中采用的是Gson组件因此给出的示例代码也是基于Gson来实现的其它的实现组件请自行搜索相关知识根据官方文档的知识来进行设置。 在Gson中主要是采用SerializedName(AUTO_FLAG)这个注解注解后面的字段是通过接口返回的数据字段。把这个注解配置到属性中表示当前属性对应哪个接口的字段。关键代码如下
package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
Data
ToString
AllArgsConstructor
NoArgsConstructor
public class CeicEarthquake implements Serializable{private static final long serialVersionUID -1212153879708670015L;private Long pkId;//主键SerializedName(AUTO_FLAG)private String autoFlag;SerializedName(CATA_ID)private String cataId;SerializedName(CATA_TYPE)private String cataType;SerializedName(EPI_DEPTH)private BigDecimal epiDepth new BigDecimal(0.0);SerializedName(EPI_LAT)private String epiLat;//纬度SerializedName(EPI_LON)private String epiLon;SerializedName(EQ_CATA_TYPE)private String eqCataType;SerializedName(EQ_TYPE)private String eqType;SerializedName(IS_DEL)private String isDel;SerializedName(LOCATION_C)private String locationC;SerializedName(LOCATION_S)private String locationS;SerializedName(LOC_STN)private String locStn;SerializedName(M)private String m;SerializedName(M_MB)private String mmb;SerializedName(M_MB2)private String mmb2;SerializedName(M_ML)private String mml;SerializedName(M_MS)private String mms;SerializedName(M_MS7)private String mms7;SerializedName(NEW_DID)private String newDid;SerializedName(O_TIME)private Date oTime;SerializedName(O_TIME_FRA)private String oTimeFra;SerializedName(SAVE_TIME)private Date saveTime;SerializedName(SUM_STN)private String sumStn;SerializedName(SYNC_TIME)private Date syncTime;SerializedName(id)private String epiId;
} 通过以上的代码就可以实现将接口返回的参数映射成符合我们需求的JavaBean。
2、JavaBean与数据库字段映射 众所周知数据的命名一般是用小写而且单词之间一般使用下划线连接起来。而Java中对属性的命名与数据库的字段还是有一定的差异。好在我们采用的是Mybatis_Plus这个框架可以实现数据库字段和JavaBean的对应。为了后续介绍方便这里将直接给出空间字段的设置。以实体类代码的形式给出。在Mybatis_Plus中主要采用TableField(valuecata_type)来进行数据库字段的设置。完整的代码如下所示
package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.google.gson.annotations.SerializedName;
import com.yelang.framework.handler.PgGeometryTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
Data
ToString
AllArgsConstructor
NoArgsConstructor
TableName(value biz_ceic_earthquake,autoResultMap true)
public class CeicEarthquake implements Serializable{private static final long serialVersionUID -1212153879708670015L;TableId(valuepk_id)private Long pkId;//主键SerializedName(AUTO_FLAG)TableField(valueauto_flag)private String autoFlag;SerializedName(CATA_ID)TableField(valuecata_id)private String cataId;SerializedName(CATA_TYPE)TableField(valuecata_type)private String cataType;SerializedName(EPI_DEPTH)TableField(valueepi_depth)private BigDecimal epiDepth new BigDecimal(0.0);SerializedName(EPI_LAT)TableField(valueepi_lat)private String epiLat;//纬度SerializedName(EPI_LON)TableField(valueepi_lon)private String epiLon;SerializedName(EQ_CATA_TYPE)TableField(valueeq_cata_type)private String eqCataType;SerializedName(EQ_TYPE)TableField(valueeq_type)private String eqType;SerializedName(IS_DEL)TableField(valueis_del)private String isDel;SerializedName(LOCATION_C)TableField(valuelocation_c)private String locationC;SerializedName(LOCATION_S)TableField(valuelocation_s)private String locationS;SerializedName(LOC_STN)TableField(valueloc_stn)private String locStn;SerializedName(M)TableField(valuem)private String m;SerializedName(M_MB)TableField(valuemmb)private String mmb;SerializedName(M_MB2)TableField(valuemmb2)private String mmb2;SerializedName(M_ML)TableField(valuemml)private String mml;SerializedName(M_MS)TableField(valuemms)private String mms;SerializedName(M_MS7)TableField(valuemms7)private String mms7;SerializedName(NEW_DID)TableField(valuenew_did)private String newDid;SerializedName(O_TIME)TableField(valueo_time)private Date oTime;SerializedName(O_TIME_FRA)TableField(valueo_time_fra)private String oTimeFra;SerializedName(SAVE_TIME)TableField(valuesave_time)private Date saveTime;SerializedName(SUM_STN)TableField(valuesum_stn)private String sumStn;SerializedName(SYNC_TIME)TableField(valuesync_time)private Date syncTime;SerializedName(id)TableField(valueepi_id)private String epiId;TableField(typeHandler PgGeometryTypeHandler.class)private String geom;TableField(existfalse)private String geomJson;
}二、空间数据表设计 在很多的技术博客当中都提到过如何进行空间数据库的设计与常规的关系型数据库表不一样的是空间数据库多了空间信息的存储的查询。以地震信息为例就包含了其经纬度坐标信息。因此这里使用PostGIS作为空间数据库存储空间信息。 在讲解改表是我们首先根据接口的字段来定义其关键属性字段然后自己设计Geometry字段通过爬取的经纬度信息来生成Geometry信息然后保存到相应的字段当中。
1、表结构设计 主要表结构设计如下包含了通过接口返回的基本信息 生成出来的SQL语句如下如果需要的话可以直接使用这里直接提供供大家参考。
CREATE TABLE public.biz_ceic_earthquake (pk_id int8 NOT NULL,auto_flag varchar(30) COLLATE pg_catalog.default,cata_id varchar(30) COLLATE pg_catalog.default,cata_type varchar(30) COLLATE pg_catalog.default,epi_depth numeric(11,8),epi_lat varchar(15) COLLATE pg_catalog.default,epi_lon varchar(15) COLLATE pg_catalog.default,eq_cata_type varchar(30) COLLATE pg_catalog.default,eq_type varchar(30) COLLATE pg_catalog.default,is_del varchar(6) COLLATE pg_catalog.default,location_c varchar(255) COLLATE pg_catalog.default,location_s varchar(100) COLLATE pg_catalog.default,loc_stn varchar(20) COLLATE pg_catalog.default,m varchar(10) COLLATE pg_catalog.default,mmb varchar(10) COLLATE pg_catalog.default,mmb2 varchar(10) COLLATE pg_catalog.default,mml varchar(10) COLLATE pg_catalog.default,mms varchar(10) COLLATE pg_catalog.default,mms7 varchar(10) COLLATE pg_catalog.default,new_did varchar(16) COLLATE pg_catalog.default,o_time timestamp(6),o_time_fra varchar(10) COLLATE pg_catalog.default,save_time timestamp(6),sum_stn varchar(10) COLLATE pg_catalog.default,sync_time timestamp(6),epi_id varchar(10) COLLATE pg_catalog.default,geom public.geometry,CONSTRAINT pk_biz_ceic_earthquake PRIMARY KEY (pk_id)
);
CREATE INDEX idx_biz_ceic_earthquake_eqidept ON public.biz_ceic_earthquake USING btree (epi_depth pg_catalog.numeric_ops ASC NULLS LAST
);
CREATE INDEX idx_biz_ceic_earthquake_geom ON public.biz_ceic_earthquake USING gist (geom public.gist_geometry_ops_2d
);
CREATE INDEX idx_biz_ceic_earthquake_m ON public.biz_ceic_earthquake USING btree (m COLLATE pg_catalog.default pg_catalog.text_ops ASC NULLS LAST
);
COMMENT ON COLUMN public.biz_ceic_earthquake.pk_id IS 主键id; 为了在查询的时候提高查询性能我们建立三个索引两个普通索引和一个空间索引构建在geom这个字段上的。后期如果要做空间分析可以使用空间索引进行查询效率提升。
三、PostGIS数据保存 设计好了地震信息空间数据表信息接口也进行了定义。万事俱备只欠东风只需要采用Mybatis_Plus组件将爬取的信息通过接口保存到PostGIS空间数据库中即可。在第一节中其实已经将实现接口参数转换成数据库字段关于实体类的定义在此不赘述这里只将数据入库的流程和方法进行简单介绍。ORM框架采用Mybatis_Plus框架。
1、Mapper接口定义 mapper接口相当于是数据库操作的总入口由于这里仅演示如何插入数据暂时没有其它的业务需求因此接口中除集成的方法暂不新增新的方法。
package com.yelang.project.extend.earthquake.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
public interface CeicEarthquakeMapper extends BaseMapperCeicEarthquake{
}2、Service逻辑层实现 业务逻辑层也比较简单为了演示效果同样不增加额外的方法仅实现MP自带的批量插入功能来实现数据插入。
package com.yelang.project.extend.earthquake.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.mapper.CeicEarthquakeMapper;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
Service
public class CeicEarthquakeServiceImpl extends ServiceImplCeicEarthquakeMapper, CeicEarthquake implements ICeicEarthquakeService{
}
3、数据入库 数据入库主要是调用ICeicEarthquakeService的批量插入方法。这里采用Junit测试套件进行爬取测试。实际情况可以内置到SpringBoot的一个方法或者定时任务当中。在这里需要注意的一个地方就是我们在数据库中定义了一个Geometry字段来存储空间点信息。因此在信息爬取过程中需要动态生成主要是手动构造Wkt格式的数据通过PgGeometryTypeHandler来实现空间类型转换看过博客的朋友应该对这种操作方法很熟悉。爬取及入库的代码如下
package com.yelang.project;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.parser.strategy.NonPageParser;
import com.yelang.common.utils.StringUtils;
import com.yelang.project.extend.earthquake.domain.crawler.CeicDateAdapter;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquakeCrawler;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
SpringBootTest
RunWith(SpringRunner.class)
public class TestXxlCrawerCeic {Autowiredprivate ICeicEarthquakeService service;Testpublic void testGetCeic() {String commonUrl https://www.ceic.ac.cn/ajax/search?startendjingdu1jingdu2weidu1weidu2height1height2zhenji1zhenji2_ System.currentTimeMillis();String[] urlList new String[20];urlList[0] commonUrl page 1;// 构造爬虫XxlCrawler crawler new XxlCrawler.Builder().setUrls(urlList).setThreadCount(3).setPauseMillis(3000).setUserAgent(Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36).setIfPost(false).setFailRetryCount(3)// 重试三次.setPageParser(new NonPageParser() {public void parse(String url, String pageSource) {if (!StringUtils.isBlank(pageSource)) {pageSource pageSource.substring(1, pageSource.length() - 1);Gson gson new GsonBuilder().registerTypeAdapter(Date.class, new CeicDateAdapter()).create();CeicEarthquakeCrawler crawler gson.fromJson(pageSource, CeicEarthquakeCrawler.class);System.out.println(总页数crawler.getNum());for (CeicEarthquake data : crawler.getShuju()) {String geom SRID 4326 ;POINT ( data.getEpiLon() data.getEpiLat());//拼接srid实现动态写入System.out.println(data);System.out.println(geom);data.setGeom(geom);}service.saveBatch(crawler.getShuju(), 300);}}}).build();crawler.start(true);// 启动}
} 上面代码的关键就是WKT的构造默认采用4326坐标系
String geom SRID 4326 ;POINT ( data.getEpiLon() data.getEpiLat());//拼接srid实现动态写入
4、运行实例及结果 使用Junit的测试套件运行上述方法在控制台可以看到如下的打印结果 很明显在控制台中看到批量插入语句和信息爬取信息示例信息如下
CeicEarthquake(pkIdnull, autoFlagM, cataIdCD20240407190310.00, cataType, epiDepth18, epiLat41.89, epiLon82.17, eqCataType, eqTypeM, isDel, locationC新疆阿克苏地区拜城县, locationS, locStn0, m4.2, mmb0, mmb20, mml0, mms0, mms70, newDidCD20240407190310, oTimeSun Apr 07 19:03:09 CST 2024, oTimeFra0, saveTimeSun Apr 07 19:08:03 CST 2024, sumStn0, syncTimeSun Apr 07 19:08:03 CST 2024, epiId46366, geomnull, geomJsonnull)
SRID4326;POINT (82.17 41.89)
CeicEarthquake(pkIdnull, autoFlagM, cataIdCD20240407182216.00, cataType, epiDepth15, epiLat41.91, epiLon82.00, eqCataType, eqTypeM, isDel, locationC新疆阿克苏地区拜城县, locationS, locStn0, m3.0, mmb0, mmb20, mml0, mms0, mms70, newDidCD20240407182216, oTimeSun Apr 07 18:22:16 CST 2024, oTimeFra0, saveTimeSun Apr 07 18:27:58 CST 2024, sumStn0, syncTimeSun Apr 07 18:27:58 CST 2024, epiId46365, geomnull, geomJsonnull)
SRID4326;POINT (82.00 41.91)
19:43:44.403 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - Preparing: INSERT INTO biz_ceic_earthquake ( pk_id, auto_flag, cata_id, cata_type, epi_depth, epi_lat, epi_lon, eq_cata_type, eq_type, is_del, location_c, location_s, loc_stn, m, mmb, mmb2, mml, mms, mms7, new_did, o_time, o_time_fra, save_time, sum_stn, sync_time, epi_id, geom ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
19:43:44.548 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - Parameters: 1780562787278299138(Long), M(String), CD20240411005512.00(String), (String), 12(BigDecimal), 24.14(String), 121.87(String), (String), M(String), (String), 台湾花莲县海域(String), (String), 0(String), 4.4(String), 0(String), 0(String), 0(String), 0(String), 0(String), CD20240411005512(String), 2024-04-11 00:55:12.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 46385(String), SRID4326;POINT(121.87 24.14)(PGgeometry)最后来看一下在PostGIS当中是否将数据成功入库在客户端中执行以下查询语句
select * from biz_ceic_earthquake; 通过上述界面看到通过XxlCrawler爬取的信息就成功的保存到了PostGIS空间数据库中。
总结 以上就是本文的主要内容本文即紧紧围绕着将信息保存到空间数据库的目标重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。行文仓促定有不足欢迎朋友们在评论浏览批评指正不胜感激。