You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求将R爬虫脚本转为可配置参数的JavaScript函数(VSCode环境)

解决Sikafinance数据爬取的JavaScript函数实现问题

我正在学习JavaScript,使用VSCode编辑器,需要把现有的R爬虫脚本转换成JS代码,实现循环获取全部可用数据的功能。目标是创建可配置ticker、datedeb、datefin、xperiod参数的函数,爬取Sikafinance网站对应BRVMAG数据页面的接口数据。

原R代码

library(httr2)
library(magrittr)

r <- request("https://www.sikafinance.com/api/general/GetHistos") %>% 
  req_body_json(list('ticker'= 'BRVMAG', 'datedeb'= '2022-02-01', 'datefin'= '2022-03-29','xperiod'= '0')) %>% 
  req_perform() %>%
  resp_body_json(simplifyVector = T)

现有JS代码及问题

我写的JS代码无法正常获取数据,主要问题有:

  • mode: "no-cors"会限制浏览器读取响应内容,导致无法解析返回的JSON
  • 硬编码了浏览器特定的sec-ch-ua等请求头,这些不是接口必需的,反而可能引发问题
  • 请求体用字符串拼接,不如直接传对象再序列化更易维护
  • 重复定义了method: "POST"
const options = {
    method: 'POST',
    headers: {
      "accept": "*/*",
      "accept-language": "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7",
      "content-type": "application/json;charset=UTF-8",
      "sec-ch-ua": "\"Chromium\";v=\"104\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"104\"",
      "sec-ch-ua-mobile": "?1",
      "sec-ch-ua-platform": "\"Android\"",
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin"
    },
    "referrer": "https://www.sikafinance.com/marches/historiques?s=BRVMAG",
    "referrerPolicy": "strict-origin-when-cross-origin",
    "body": "{\"ticker\":\"BRVMAG\",\"datedeb\":\"2022-06-19\",\"datefin\":\"2022-08-16\",\"xperiod\":\"0\"}",
    "method": "POST",
    "mode": "no-cors",
    "credentials": "include"
  };
  
  fetch('https://www.sikafinance.com/api/general/GetHistos', options)
    .then(response => response.text())
    .then(response => console.log(response))
    .catch(err => console.error(err));

修复后的可配置参数函数

使用async/await语法编写更清晰的异步函数,简化请求头,正确处理请求体和响应:

/**
 * 获取Sikafinance历史数据的异步函数
 * @param {string} ticker - 股票代码,如BRVMAG
 * @param {string} datedeb - 起始日期,格式YYYY-MM-DD
 * @param {string} datefin - 结束日期,格式YYYY-MM-DD
 * @param {string} xperiod - 周期参数,如"0"
 * @returns {Promise<Array>} 返回历史数据数组
 */
async function getSikaFinanceHistos(ticker, datedeb, datefin, xperiod) {
  const url = 'https://www.sikafinance.com/api/general/GetHistos';
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({ ticker, datedeb, datefin, xperiod }),
    credentials: 'include'
  };

  try {
    const response = await fetch(url, options);
    if (!response.ok) throw new Error(`请求失败:${response.status}`);
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('获取数据出错:', error);
    throw error;
  }
}

// 示例调用
getSikaFinanceHistos('BRVMAG', '2022-02-01', '2022-03-29', '0')
  .then(data => console.log('获取到的数据:', data))
  .catch(err => console.error(err));

循环获取全量数据实现

如果接口对单次请求的时间范围有限制,可按固定时间间隔拆分日期区间,循环请求后合并数据:

/**
 * 拆分日期区间为多个子区间
 * @param {string} startDate - 起始日期YYYY-MM-DD
 * @param {string} endDate - 结束日期YYYY-MM-DD
 * @param {number} daysPerChunk - 每个子区间的天数
 * @returns {Array<{start: string, end: string}>} 拆分后的日期区间数组
 */
function splitDateRange(startDate, endDate, daysPerChunk = 30) {
  const start = new Date(startDate);
  const end = new Date(endDate);
  const chunks = [];
  let currentStart = new Date(start);

  while (currentStart <= end) {
    let currentEnd = new Date(currentStart);
    currentEnd.setDate(currentEnd.getDate() + daysPerChunk - 1);
    if (currentEnd > end) currentEnd = end;

    chunks.push({
      start: currentStart.toISOString().split('T')[0],
      end: currentEnd.toISOString().split('T')[0]
    });

    currentStart.setDate(currentEnd.getDate() + 1);
  }
  return chunks;
}

/**
 * 批量获取全量历史数据
 * @param {string} ticker - 股票代码
 * @param {string} startDate - 总起始日期
 * @param {string} endDate - 总结束日期
 * @param {string} xperiod - 周期参数
 * @param {number} daysPerChunk - 每次请求的天数区间
 * @returns {Promise<Array>} 合并后的全量数据
 */
async function getAllSikaFinanceHistos(ticker, startDate, endDate, xperiod, daysPerChunk = 30) {
  const dateChunks = splitDateRange(startDate, endDate, daysPerChunk);
  const allData = [];

  for (const chunk of dateChunks) {
    console.log(`正在获取区间:${chunk.start} 至 ${chunk.end}`);
    try {
      const data = await getSikaFinanceHistos(ticker, chunk.start, chunk.end, xperiod);
      allData.push(...data);
      // 避免请求过于频繁,添加延迟
      await new Promise(resolve => setTimeout(resolve, 1000));
    } catch (error) {
      console.error(`获取区间${chunk.start}至${chunk.end}失败:`, error);
    }
  }

  return allData;
}

// 示例调用:获取2022年全年数据
getAllSikaFinanceHistos('BRVMAG', '2022-01-01', '2022-12-31', '0')
  .then(fullData => {
    console.log('全量数据获取完成,总条数:', fullData.length);
    // 可在这里处理或保存数据
  })
  .catch(err => console.error(err));

内容的提问来源于stack exchange,提问作者Koffi Frederic Sessie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:21:32