java 场内基金爬虫与存储实战

1 前言

相信看到这篇文章的你也许买过场外基金,ETF 是一种场内基金,只有开通特定的账户才能交易。作者在之前的文章中已经介绍了 python爬虫-场内基金获取 ,在本文中将介绍如何使用 java 进行爬虫,并将爬虫数据存入数据库中。

2 环境准备

首先我们需要确认 ETF 基金的数据来源,如下图所示即我们需要抓取的数据,列表中的所有信息都会存入到数据库中,用于分析和查询ETF信息。

bash 复制代码
# 场内基金列表访问地址
http://fund.eastmoney.com/data/fbsfundranking.html

使用 Java 进行爬虫,主要是使用 http 请求(使用hutool工具类)和 jsoup 抓取页面进行页面元素处理。 根据所需要的数据信息,构建的数据库表的结构如下所示:

3 数据抓取

在 ETF 信息页面,通过浏览器控制台我们可以发现场内信息列表是通过接口来返回的,如下所示:

bash 复制代码
# 基金列表接口
http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=fb&ft=ct&rs=&gs=0&sc=clrq&st=desc&pi=1&pn=5000
# 场内基金详情页面
http://fund.eastmoney.com/513360.html
# 基金基本信息页面
http://fundf10.eastmoney.com/jbgk_002147.html
# 返回内容的分析
0 513100, 基金代码
1 国泰纳斯达克100ETF, 基金名称
2 GTNSDK100ETF,
3 2023-08-24,
4 1.0780, 单位净值
5 5.39,  累计净值
6 0.37,  近一周
7 -3.58, 近一月
8 10.68, 近3月
9 28.18, 近6月
10 19.91, 近一年
11 5.54, 近两年
12 30, 近三年
13 38.56, 今年来
14 439, 成立依赖
15 2013-04-25 成立日期

通过对列表接口返回内容的分析,对比基金的详情页面,可以得到在 分析下图的接口列表,发现其返回的不是一个 json 格式的数据,接口的访问是一个 jsoup 的回调方式 ,但是去掉 var rankData =后,会发现其是一个标准的 json 格式,需要获取的数据在 datas 节点里面,每一个数据是一个 数组的方式,数组内的每一个数据都有其独特的含义,通过对比基金详情页面的内容,可以获取到数组内每个下标的数据含义,如上所示。

如下所示,即编写的爬虫代码,由于网站设置了防盗链,所以需要添加 Referer ,否则获取不到列表数据。还是使用 hutool 的 http请求工具类获取接口的返回内容。 在以上代码中,获取基金基本信息时采用 jsoup 的方式获取网页元素进行编码。在获取基金基本信息时,用到了一个 java 的知识点,如何使两个 list 按照顺序合并成一个 map。在获取基金基本信息时,通过分析可以知道其数据结构是一个 table , 但是每个基金的信息可能不全是这样的结构,所以通过位置元素的方式来获取内容容易出错。仔细观察基金名称和基金名称内容,可以知道其是不同的标签,一个是 th 一个是 td ,其顺序都是交替出现的,通过 jsoup 获取到整个 table ,然后分次获取 th 和 td 的内容,即可取到对应的值,将两个 list 合并成 map , 通过 getDefault 的方式来获取数据,既方便也可以避免空指针的问题,一举两得。

如下图所示,即是通过网页元素抓取基金基本信息的代码:

4 数据存储

通过数据的分析和抓取,已经获取到了 ETF 的基本数据,通过 mybaits-plus 进行数据的存储,使用的存储是阿里云 oceanbase 数据库。

ini 复制代码
# 抓取etf 信息列表,存储数据库
List<EtfInfo> etfInfos = TianFundUtils.etfInfoList();
stockService.saveEtfInfoList(etfInfos);

通过对今年的表现的排序,按照表现倒序排列,就可以找到表现比较好的投资标的。

场内基金的基本信息已经抓取到了,可以通过基金规模,标的去跟踪选择需要投资的品种,在爬虫之余还可以收集到一些信息,何乐而不为呢,感兴趣的朋友可以深入研究一下。

5 总结

在本文中,通过爬虫的方式获取场内基金的列表信息和基金基本信息,存入到数据库中方便分析和研究,在整个过程中还学习到了一个技术点,对投资感兴趣的朋友可以依据此进行研究和选择。项目 github 地址 springboot-auth。

相关推荐
沙蒿同学1 小时前
不引 Ghostscript:我用纯 Go 给 PDF 做了一场「压缩手术」
前端·后端·github
前进的李工3 小时前
飞书企业知识库设计+后端高频八股
数据库·redis·后端·mysql·性能优化·飞书·rag
金銀銅鐵4 小时前
[Java] 展示增删元素时 LinkedList 的内部变化
java·后端·ai编程
武子康5 小时前
Vercel Cache Reason:相同 MISS,怎样决定下一步查什么
人工智能·后端·agent
杨文说AI与数字化6 小时前
把模型依赖做成可替换的组件:三层适配 + 一套回归评估
后端
IT_陈寒6 小时前
Vue的这个响应式陷阱我居然现在才发现
前端·人工智能·后端
WL学习笔记7 小时前
使用string类
c++·后端·string类
飞鸟真人7 小时前
IM网关系列(九)单账号流量统计:滑动窗口桶方案设计与Go实现
后端·golang
武子康8 小时前
Embedding 替换怎么评测:把索引成本算进成功任务
人工智能·后端·agent
9527!到!10 小时前
Springboot @value读取配置参数踩坑&推荐解决方案
java·spring boot·spring