C#通过JS变量提取天天基金API返回的基金净值
天天基金API
常见的 API 如下:
- 所有基金代码:http://fund.eastmoney.com/js/fundcode_search.js
- 基金详细信息:http://fund.eastmoney.com/pingzhongdata/001186.js
- 基金实时信息:http://fundgz.1234567.com.cn/js/001186.js
- 所有基金公司:http://fund.eastmoney.com/js/jjjz_gs.js
本文用到的API主要是前面两个,其中001186是要查询的基金代码,接口返回的数据是一个js文件。
常规方法解析js文件里面的数据会比较繁琐,所以本文使用 Jint 库来解析数据,应该算全网首创的方法了。
添加项目依赖项
使用 NuGet 安装 RestSharp、Jint 库,用途如下
- RestSharp:用于发送HTTP请求
- Jint:用于解析js文件
请求 API 数据
使用 RestSharp 库请求API,方法如下
using RestSharp;
public static string GetFundAPIData(string url)
{
var client = new RestClient();
var request = new RestRequest(url, Method.Get);
var response = client.Execute(request);
if (response.IsSuccessful)
{
return response.Content?? string.Empty;
}
else
{
throw new Exception($"Failed to fetch data from the API: {response.ErrorMessage}");
}
}
获取所有基金代码
接口返回的数据比较长,大致结构如下:
var r = [["000001","HXCZHH","华夏成长混合","混合型-灵活","HUAXIACHENGZHANGHUNHE"],["000002","HXCZHH","华夏成长混合(后端)","混合型-灵活","HUAXIACHENGZHANGHUNHE"]];
定义一个 FundInfo 类来存储基金信息:
public class FundInfo
{
public string Code { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
调用上面的请求API方法获取接口数据,并调用下面的方法解析数据:
public static List<FundInfo> ParseFundList(string js)
{
var fundList =new List<FundInfo>();
// 初始化 Jint 引擎
Engine engine = new Engine();
// 执行 JavaScript 代码
var result = engine.Execute(js).GetValue("r");
// 确保结果是 JavaScript 数组
if (result.IsArray())
{
var jsArray = result.AsArray();
// 将 JavaScript 数组转换为 C# List<List<string>> 类型
var clrList = new List<List<string>>();
foreach (var item in jsArray)
{
var sublist = new List<string>();
foreach (var subitem in item.AsArray())
{
sublist.Add(subitem.ToString());
}
clrList.Add(sublist);
}
fundList = clrList.Select(x => new FundInfo { Code = x[0], Name = x[2], Type = x[3] }).ToList();
return fundList;
}
else
{
throw new InvalidOperationException("Expected an array but got something else.");
}
}
调用上面的方法获取结果:
// 获取所有基金代码
var js=GetFundAPIData("http://fund.eastmoney.com/js/fundcode_search.js");
var list = ParseFundList(js);
获取基金净值信息
接口返回的数据比较长,分析的时候可以使用Javascript格式化在线工具处理一下,我们需要解析的数据如下:
var Data_netWorthTrend = [{
"x": 1430841600000,
"y": 1.0,
"equityReturn": 0,
"unitMoney": ""
}, {
"x": 1431014400000,
"y": 1.004,
"equityReturn": 0,
"unitMoney": ""
}];
定义一个 NetWorthTrendItem 类存放基金净值信息:
public class NetWorthTrendItem
{
public DateTime Time { get; set; } // 时间戳
public decimal Value { get; set; } // 净值
public decimal EquityReturn { get; set; } // 涨跌幅
public string UnitMoney { get; set; } // 每份派送金
}
直接从 Jint 获取 JavaScript 数组,并将其转换为 C# 对象:
public static List<NetWorthTrendItem> GetFundValues(string js)
{
var engine = new Engine();
// 定义 JavaScript 变量
engine.Execute(js);
// 获取 JavaScript 数组
var jsArray = engine.GetValue("Data_netWorthTrend");
// 将 JavaScript 数组转换为 C# 列表
var netWorthTrendItems = ConvertJsArrayToCSharpList(jsArray);
return netWorthTrendItems;
}
private static List<NetWorthTrendItem> ConvertJsArrayToCSharpList(JsValue jsArray)
{
var array = jsArray.AsArray();
var list = new List<NetWorthTrendItem>();
for (int i = 0; i < array.Length; i++)
{
var item = array.Get(i);
var newItem = new NetWorthTrendItem
{
Time = DateTimeOffset.FromUnixTimeMilliseconds((long)item.Get("x").AsNumber()).UtcDateTime.ToLocalTime(),
Value = (decimal)item.Get("y").AsNumber(),
EquityReturn = (decimal)item.Get("equityReturn").AsNumber(),
UnitMoney = item.Get("unitMoney").AsString()
};
list.Add(newItem);
}
return list;
}
功能测试
测试代码如下:
static void Main()
{
var js1=GetFundAPIData("http://fund.eastmoney.com/js/fundcode_search.js");
var list1 = ParseFundList(js1);
Console.WriteLine(JsonSerializer.Serialize(list1.Last(), new JsonSerializerOptions()
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
}));
var js2=GetFundAPIData("http://fund.eastmoney.com/pingzhongdata/001186.js");
var list2 = GetFundValues(js2);
Console.WriteLine(JsonSerializer.Serialize(list2.Last()));
Console.ReadLine();
}
测试结果如下:
{"Code":"970214","Name":"中信建投悦享6个月持有期债券C","Type":"债券型-混合一级"}
{"Time":"2024-10-15T00:00:00+08:00","Value":2.269,"EquityReturn":-1.6,"UnitMoney":""}
实际使用时可以把基金净值接口地址里面基金代码单独提取出来,这里只是为了演示方法就不做太多封装。
参考链接
C#通过JS变量提取天天基金API返回的基金净值的更多相关文章
- javascirpt对象运用与JS变量
abcdefghijklmnopqrstuvwyz String 对象方法 charAt() 方法可返回指定位置的字符.stringObject.charAt(index)(index从0开始)[ht ...
- ejs不能读取js变量??????
一.问题描述 用express搭了一个nodejs服务端,为了测试接口数据是否能够正常输出,用ejs作为模版引擎的html文件写js发请求. 1.请求正常,能在network看到,但是没有输出cons ...
- JS 变量 相关内容
JS变量按存储方式区分为哪些类型?: js变量按照存储方式分为两种类型:值类型 和 引用类型 1.值类型(基本类型): 布尔值(boolean) . null .undefined .数值(numbe ...
- echart.js的使用与API
---恢复内容开始--- echart.js的使用与API 1.echart.js的使用: 第一步:在head标签或body下创建一个script标签去引用echart.js,(该文件可以在echar ...
- JS 数据类型转换-转换函数、强制类型转换、利用js变量弱类型转换
1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型 ...
- js中的referrer使用,返回上一页
js完整代码: <script language="javascript"> var refer=document. referrer ; document.g ...
- js变量类型和计算
# js入门基础-变量类型和计算 ` --首先由于我使用了一个不太合格的markdown来编写来文章,所以在移动端阅读不要太方便,建议移动端使用横屏模式或pc端阅读,当然如果你有平板那是最好的. -- ...
- JS变量类型与计算
一.题目 1.JS中使用typeof能得到哪些类型? 2.何时使用===何时使用==? 3.JS中有哪些内置函数? 4.JS变量按照存储方式区分为哪些类型,并描述其特点? 5.如何理解JSON? 知识 ...
- js变量前的+是什么意思
js变量前的+是什么意思 if (+value >= distance) {} 这个+什么意思 可以理解为 Number(value) 会将其按照Number函数的规则转换为数值或者NaN, ...
- Web3.js 0.20.x API 中文版翻译
文档原始链接为:https://web3.learnblockchain.cn/0.2x.x/,欢迎大家前往查阅,本文只是节选开头部分的介绍及API列表索引,以下为翻译正文: 为了开发一个基于以太坊的 ...
随机推荐
- openAI的比赛retro contest的一些细节设置(Detail)
2018年openAI公司搞了一个比赛retro contest,该比赛目的是为了在自家的库retro上测试迁移强化学习的性能,虽然这个比赛已经结束多年但是现在了解一些也是有一定益处的. 比赛细节介绍 ...
- 乌克兰学者的学术图谱case3
============================================ 背景: 弗兰采维奇材料问题研究是欧洲最大的材料科研院所,在核电.航空.航天.军工及其他装备制造领域的先进材料研 ...
- Spring 相关知识
https://www.bilibili.com/video/BV1gW411W7wy?spm_id_from=333.788.b_636f6d6d656e74.173 老雷的Spring注解驱动 源 ...
- Java反射初探123456789
牛逼的框架都反射,不要问我为什么,因为我也不知道 可能是因为生成了class文件没法实例化,所以只能反射创建对象,但是在spring中,ioc就是反射实现的控制反转 看Spring4.x企业级开发实战 ...
- 我们与高效工作流的距离:使用AI阅读工具ChatDOC+笔记软件Obsidian Slide,直接从 PDF 文献直接输出 PPT 报告
我们与高效工作流的距离 在当今信息化的时代,为了实现高效工作和学习,如何实现快速地输入和输出成为每个人的必修课题. 然而,对于输入而言,每一天大量的信息,往往会使我们陷入信息过载和知识爆炸的困境,难以 ...
- UCX84X笔记
1. 管脚定义 COMP: 误差放大器补偿引脚.将外部补偿元件连接到此引脚,以修改误差放大器输出.误差放大器内部有电流限制,因此用户可以通过外部强制COMP接地来命令零占空比. UCx84x系列中的误 ...
- 简简单单教你如何用C语言实现获取当前所有可用网口!
一.获取本机所有可用网卡名 原理: 在 Linux 系统中,/proc 目录是一个位于内存中的伪文件系统. /proc目录是内核提供给我们的查询中心,通过查询该目录下的文件内容,可以获取到有关系统硬件 ...
- 关于为什么使用 ASCII GBK Unicode编码
关于为什么使用 ASCII GBK Unicode编码 由来:大家都知道计算机最早是美国人为了更加便捷的存储和计算数据发明的,但是呢计算机底层都是硬件,只能存储像0101这样的二进制数据,那美国人为了 ...
- Oracle数据库自动备份
1.bat脚本 格式为ANSI格式 set CURDATE=%date:~0,4%%date:~5,2%%date:~8,2% set CURMON=%date:~0,4%%date:~5,2% se ...
- 【Mac】之安装FileZilla
FileZilla下载地址:http://www.pc6.com/mac/111230.html 连接FTP服务器: 下载完成之后需要修改字符集编码: ①先添加站点 ②填写:gb2312字符集