翼度科技»论坛 编程开发 .net 查看内容

C#通过JS变量提取天天基金API返回的基金净值

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
目录

天天基金API

常见的 API 如下:
本文用到的API主要是前面两个,其中001186是要查询的基金代码,接口返回的数据是一个js文件。
常规方法解析js文件里面的数据会比较繁琐,所以本文使用 Jint 库来解析数据,应该算全网首创的方法了。
添加项目依赖项

使用 NuGet 安装 RestSharp、Jint 库,用途如下

  • RestSharp:用于发送HTTP请求
  • Jint:用于解析js文件
请求 API 数据

使用 RestSharp 库请求API,方法如下
  1. using RestSharp;
  2. public static string GetFundAPIData(string url)
  3. {
  4.     var client = new RestClient();
  5.     var request = new RestRequest(url, Method.Get);
  6.     var response = client.Execute(request);
  7.     if (response.IsSuccessful)
  8.     {
  9.         return response.Content?? string.Empty;
  10.     }
  11.     else
  12.     {
  13.         throw new Exception($"Failed to fetch data from the API: {response.ErrorMessage}");
  14.     }
  15. }
复制代码
获取所有基金代码

接口返回的数据比较长,大致结构如下:
  1. var r = [["000001","HXCZHH","华夏成长混合","混合型-灵活","HUAXIACHENGZHANGHUNHE"],["000002","HXCZHH","华夏成长混合(后端)","混合型-灵活","HUAXIACHENGZHANGHUNHE"]];
复制代码
定义一个 FundInfo 类来存储基金信息:
  1. public class FundInfo
  2. {
  3.     public string Code { get; set; }
  4.     public string Name { get; set; }
  5.     public string Type { get; set; }
  6. }
复制代码
调用上面的请求API方法获取接口数据,并调用下面的方法解析数据:
  1. public static List<FundInfo> ParseFundList(string js)
  2. {
  3.     var fundList =new List<FundInfo>();
  4.     // 初始化 Jint 引擎
  5.     Engine engine = new Engine();
  6.     // 执行 JavaScript 代码
  7.     var result = engine.Execute(js).GetValue("r");
  8.     // 确保结果是 JavaScript 数组
  9.     if (result.IsArray())
  10.     {
  11.         var jsArray = result.AsArray();
  12.         // 将 JavaScript 数组转换为 C# List<List<string>> 类型
  13.         var clrList = new List<List<string>>();
  14.         foreach (var item in jsArray)
  15.         {
  16.             var sublist = new List<string>();
  17.             foreach (var subitem in item.AsArray())
  18.             {
  19.                 sublist.Add(subitem.ToString());
  20.             }
  21.             clrList.Add(sublist);
  22.         }
  23.         fundList = clrList.Select(x => new FundInfo { Code = x[0], Name = x[2], Type = x[3] }).ToList();
  24.         return fundList;
  25.     }
  26.     else
  27.     {
  28.         throw new InvalidOperationException("Expected an array but got something else.");
  29.     }
  30. }
复制代码
调用上面的方法获取结果:
  1. // 获取所有基金代码
  2. var js=GetFundAPIData("http://fund.eastmoney.com/js/fundcode_search.js");
  3. var list = ParseFundList(js);
复制代码
获取基金净值信息

接口返回的数据比较长,分析的时候可以使用Javascript格式化在线工具处理一下,我们需要解析的数据如下:
  1. var Data_netWorthTrend = [{
  2.     "x": 1430841600000,
  3.     "y": 1.0,
  4.     "equityReturn": 0,
  5.     "unitMoney": ""
  6. }, {
  7.     "x": 1431014400000,
  8.     "y": 1.004,
  9.     "equityReturn": 0,
  10.     "unitMoney": ""
  11. }];
复制代码
定义一个 NetWorthTrendItem 类存放基金净值信息:
  1. public class NetWorthTrendItem
  2. {
  3.     public DateTime Time { get; set; } // 时间戳
  4.     public decimal Value { get; set; } // 净值
  5.     public decimal EquityReturn { get; set; } // 涨跌幅
  6.     public string UnitMoney { get; set; } // 每份派送金
  7. }
复制代码
直接从 Jint 获取 JavaScript 数组,并将其转换为 C# 对象:
  1. public static List<NetWorthTrendItem> GetFundValues(string js)
  2. {
  3.     var engine = new Engine();
  4.     // 定义 JavaScript 变量
  5.     engine.Execute(js);
  6.     // 获取 JavaScript 数组
  7.     var jsArray = engine.GetValue("Data_netWorthTrend");
  8.     // 将 JavaScript 数组转换为 C# 列表
  9.     var netWorthTrendItems = ConvertJsArrayToCSharpList(jsArray);
  10.     return netWorthTrendItems;
  11.    
  12. }
  13. private static List<NetWorthTrendItem> ConvertJsArrayToCSharpList(JsValue jsArray)
  14. {
  15.     var array = jsArray.AsArray();
  16.     var list = new List<NetWorthTrendItem>();
  17.     for (int i = 0; i < array.Length; i++)
  18.     {
  19.         var item = array.Get(i);
  20.         var newItem = new NetWorthTrendItem
  21.         {
  22.             Time = DateTimeOffset.FromUnixTimeMilliseconds((long)item.Get("x").AsNumber()).UtcDateTime.ToLocalTime(),
  23.             Value = (decimal)item.Get("y").AsNumber(),
  24.             EquityReturn = (decimal)item.Get("equityReturn").AsNumber(),
  25.             UnitMoney = item.Get("unitMoney").AsString()
  26.         };
  27.         list.Add(newItem);
  28.     }
  29.     return list;
  30. }
复制代码
功能测试

测试代码如下:
  1. static void Main()
  2. {
  3.     var js1=GetFundAPIData("http://fund.eastmoney.com/js/fundcode_search.js");
  4.     var list1 = ParseFundList(js1);
  5.     Console.WriteLine(JsonSerializer.Serialize(list1.Last(), new JsonSerializerOptions()
  6.     {
  7.         Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
  8.     }));
  9.     var js2=GetFundAPIData("http://fund.eastmoney.com/pingzhongdata/001186.js");
  10.     var list2 = GetFundValues(js2);
  11.     Console.WriteLine(JsonSerializer.Serialize(list2.Last()));
  12.     Console.ReadLine();
  13. }
复制代码
测试结果如下:
  1. {"Code":"970214","Name":"中信建投悦享6个月持有期债券C","Type":"债券型-混合一级"}
  2. {"Time":"2024-10-15T00:00:00+08:00","Value":2.269,"EquityReturn":-1.6,"UnitMoney":""}
复制代码
实际使用时可以把基金净值接口地址里面基金代码单独提取出来,这里只是为了演示方法就不做太多封装。
参考链接


来源:https://www.cnblogs.com/timefiles/p/18469990
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具