股票数据采集
大约 8 分钟
股票数据采集
目标
- 掌握RestTemplate基本使⽤;
- 阅读并理解第三⽅股票接⼝API;
- 基于RestTemplate实现国内⼤盘数据采集功能;
- 基于RestTemplate实现国内板块和股票流⽔数据采集功能;
- 熟悉mybatis批量插⼊实现;
1. 股票数据采集环境准备
股票数据采集环境准备
当前项⽬中的股票数据都是历史数据,不是实时最新的数据,⽽要想获取股票最新的数据,就需要定时调⽤第三⽅接⼝拉取最新数据流⽔;
Spring框架已为我们封装了⼀套访问远程http接⼝的模板⼯具:RestTemplate
,借助于该⼯具,我们可访问第三⽅股票接⼝,获取股票最新数据。 RestTemplate
本质上就是⼀个⾮常轻量级http客户端
,使⽤简单且容易上⼿;
股票数据采集核⼼流程如下:

常⻅http客户端组件:
- RestTemplate:Spring提供,轻量易上⼿;
- HttpClient:apache提供;
- OkHttpClient
⼯程搭建代码操作:
⼯程搭建
- 在stock_parent⼯程下构建stock_job⼦⼯程,并在pom中引⼊依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>stock_parent</artifactId>
<groupId>com.itheima.stock</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>stock_job</artifactId>
<description>
该工程用于股票数据的采集工程
</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--引入公共依赖-->
<dependency>
<groupId>com.itheima.stock</groupId>
<artifactId>stock_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--引入web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入单元测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<!--打包名称-->
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.yml主配置⽂件与stock_backend⼯程⼀致:
# 定义端口号
server:
port: 8092
# 配置数据源
spring:
datasource:
druid:
username: root
password: root
url: jdbc:mysql://192.168.200.129:3306/stock_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
# 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时
initialSize: 6
# 最小连接池数量
minIdle: 2
# 最大连接池数量
maxActive: 20
# 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,
# 并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。
maxWait: 60000
profiles:
active: stock # 激活|加载其它配置资源
# 配置mybatis
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印运行的sql
type-aliases-package: com.itheima.stock.pojo.entity # 批量给指定包下的实体类取别名,方便xml使用,默认是类名,首字母小写
mapper-locations: classpath:mapper/*.xml # 加载类路径下的mapper下的所有xml文件
# 设置分页
pagehelper:
helper-dialect: mysql #指定分页数据库类型(方言)
reasonable: true #合理查询超过最大页,则查询最后一页
- 添加main启动类:
package com.itheima.stock;
@SpringBootApplication
@MapperScan("com.itheima.stock.mapper")
public class JobApp {
public static void main(String[] args) {
SpringApplication.run(JobApp.class, args);
}
}
- 工程结构如下:

配置RestTemplate
- 在stock_job⼯程下配置RestTemplate bean对象
@Configuration
public class HttpClientConfig {
/**
* 定义restTemplate bean
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
说明:RestTemplate是⼀个java Http的客户端,可以模拟浏览器的访问⾏为,获取接⼝数据;
RestTemplate快速⼊⻔
- RestTemplate API⼊⻔-1
@SpringBootTest
public class TestRestTemplate {
@Autowired
private RestTemplate restTemplate;
/**
* 测试get请求携带url参数,访问外部接⼝
* */
@Test
public void test01(){
String url="http://localhost:6666/account/getByUserNameAndAddress?userName=itheima&address=shanghai";
/*
参数1:url请求地址
参数2:请求返回的数据类型
*/
ResponseEntity<String> result =restTemplate.getForEntity(url, String.class);
//获取响应头
HttpHeaders headers = result.getHeaders();
System.out.println(headers.toString());
//响应状态码
int statusCode = result.getStatusCodeValue();
System.out.println(statusCode);
//响应数据
String respData = result.getBody();
System.out.println(respData);
}
}

get请求响应数据⾃动封装vo实体对象
/**
* 测试响应数据⾃动封装到vo对象
*/
@Test
public void test02(){
String url="http://localhost:6666/account/getByUserNameAndAddress?userName=itheima&address=shanghai";
/*
参数1:url请求地址
参数2:请求返回的数据类型
*/
Account account = restTemplate.getForObject(url,Account.class);
System.out.println(account);
}
@Data
public static class Account {
private Integer id;
private String userName;
private String address;
}
- POST请求模拟form表单访问外部接⼝
/**
* post模拟form表单提交数据
*/
@Test
public void test04(){
String
url="http://localhost:6666/account/addAccount";
//设置请求头,指定请求数据⽅式
HttpHeaders headers = new HttpHeaders();
//告知被调⽤⽅,请求⽅式是form表单提交,这样对⽅解析数据时,就会按照form表单的⽅式解析处理
headers.add("Content-type","application/x-www-formurlencoded");
//组装模拟form表单提交数据,内部元素相当于form表单的input框
LinkedMultiValueMap<String, Object> map = new
LinkedMultiValueMap<>();
map.add("id","10");
map.add("userName","itheima");
map.add("address","shanghai");
HttpEntity<LinkedMultiValueMap<String, Object>>
httpEntity = new HttpEntity<>(map, headers);
/*
参数1:请求url地址
参数2:请求⽅式 POST
参数3:请求体对象,携带了请求头和请求体相关的参数
参数4:响应数据类型
*/
ResponseEntity<Account> exchange =
restTemplate.exchange(url, HttpMethod.POST, httpEntity,
Account.class);
Account body = exchange.getBody();
System.out.println(body);

- POST请求发送JSON数据
/**
* post发送json数据
*/
@Test
public void test05(){
String url="http://localhost:6666/account/updateAccount";
//设置请求头的请求参数类型
HttpHeaders headers = new HttpHeaders();
//告知被调⽤⽅,发送的数据格式的json格式,对⽅要以json的⽅式解析处理
headers.add("Content-type","application/json;charset=utf-8");
//组装json格式数据
String jsonReq="{\"address\":\"上海\",\"id\":\"1\",\"userName\":\"zhangsan\"}";
//构建请求对象
HttpEntity<String> httpEntity = new HttpEntity<>(jsonReq, headers);
/*
发送数据
参数1:请求url地址
参数2:请求⽅式
参数3:请求体对象,携带了请求头和请求体相关的参数
参数4:响应数据类型
*/
ResponseEntity<Account> responseEntity =restTemplate.exchange(url, HttpMethod.POST, httpEntity,
Account.class);
//或者
// Account account=restTemplate.postForObject(url,httpEntity,Account.class);
Account body = responseEntity.getBody();
System.out.println(body);
}
- 获取接⼝响应的cookie数据
/**
* 获取请求cookie值
*/
@Test
public void test06(){
String url="http://localhost:6666/account/getCookie";
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
//获取cookie
List<String> cookies = result.getHeaders().get("Set-Cookie");
//获取响应数据
String resStr = result.getBody();
System.out.println(resStr);
System.out.println(cookies);
}
2. 股票数据采集接⼝介绍
前言
⽬前市⾯上有⼀些正规的API⾦融接⼝,可为我们提供实时的股票⾦融数据,同时也提供有较为完整的开发⽂档,⽤起来也会更⽅便⼀些,但是⼤多是付费的,在这⾥给⼤家梳理了常⽤的股票API接⼝:
day05\资料\股票接⼝
项⽬中股票数据主要来⾃新浪
提供的公共接⼝,通过RestTemplate
采集股票相关数据,完成A股⼤盘、外盘、板块、个股等数据的实时采集
⼯作;
接⼝相关信息如下:
- 采集国内⼤盘实时数据
- 接⼝地址:
http://hq.sinajs.cn/list=sh000001,sz399001
- 响应数据格式:
- 接⼝地址:
- 采集国外⼤盘实时数据
- 接⼝地址:
http://hq.sinajs.cn/list=sh000001,sz399001
- 响应数据格式:
- 接⼝地址:
- 采集A股个票实时数据
- 接⼝地址:
http://hq.sinajs.cn/list=sh000001,sz399001
- 响应数据格式:
- 接⼝地址:
- 采集国内板块⾏情数据
- 接⼝地址:
http://hq.sinajs.cn/list=sh000001,sz399001
- 响应数据格式:
- 接⼝地址:
3. 股票相关数据采集
3.1 A股⼤盘数据采集
前言
代码操作
- 配置ID⽣成器bean
A股⼤盘数据采集⼊库时,主键ID保证唯⼀,所以在stock_job⼯程配置ID⽣成器:
@Configuration
public class CommonConfig {
/**
* 配置基于雪花算法⽣成全局唯⼀id
* 参与元算的参数: 时间戳 + 机房id + 机器id + 序列号
* 保证id唯⼀
* @return
*/
@Bean
public IdWorker idWorker(){
//指定当前为1号机房的2号机器⽣成
return new IdWorker(2L,1L);
}
}
股票常量数据配置
- 配置股票地址参数 在
stock_job
⼯程下,定义股票相关配置⽂件application-stock.yml
,该⽂件与stock_backend下的配置⼀致,然后我们把⼤盘、板块、股票相关的通⽤参数配置进来:
# 配置股票相关的参数 stock: inner: # 国内⼤盘ID - sh000001 # 上证ID - sz399001 # 深证ID outer: # 外盘ID - int_dji # 道琼斯 - int_nasdaq # 纳斯达克 - int_hangseng # 恒⽣ - int_nikkei # ⽇经指数 - b_TWSE # 台湾加权 - b_FSSTI # 新加坡 marketUrl: http://hq.sinajs.cn/list= blockUrl: http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php
- 配置股票地址参数 在
股票常量数据封装
在stock_common⼯程继续完善StockInfoConfig类:
@ConfigurationProperties(prefix = "stock") @Data public class StockInfoConfig { private List<String> inner; //外盘ID集合 private List<String> outer; //⼤盘参数获取url private String marketUrl; //板块参数获取url private String blockUrl; }
- 在公共配置类上开启配置
@EnableConfigurationProperties(StockInfoConfig.class)//开启常⽤参数配置bean @Configuration public class CommonConfig { //...... }
A股⼤盘响应数据说明

var hq_str_sh000001="上证指
数,3358.9338,3361.5177,3398.6161,3417.0085,3358.9338,0,0,38
1243178,510307202948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2022-06-30,15:30:39,00,";
参数说明:
0:指数名称
1:开盘点
2:前收盘点
3:当前点
4:最⾼点
5:最低点
8:成交量
9:成交⾦额
30:当前⽇期
31:当前时间
面试点: