JavaScript向函数传递列表元素调用Yahoo Stock API报错如何解决
问题原因
你的代码存在以下几处核心问题,最终导致API调用失败触发报错:
- 异步函数未等待返回结果:
read_fortune_500是async异步函数,调用时不加await的话,返回的是Pending状态的Promise对象,不是实际的股票代码值,传给API后无法识别,触发返回结果的解析错误。 - 股票代码存储逻辑错误:你初始将
stockSymbol定义为数组,但在循环中直接用stockSymbol = tdValue赋值,每次都会覆盖上一次的结果,最终只能拿到最后一个遍历到的股票代码。如果要存储多个股票代码,应该用数组的push()方法追加内容。 - 冗余的DOM遍历逻辑:你选中的
#constituents > tbody > tr > td:nth-child(1)本身就是存储股票代码的单元格,直接取该元素的text内容即可,不需要额外遍历子元素。 - 函数参数命名冲突:全局变量
stockSymbol和collect_stocks的形参重名,容易引发作用域混乱。 - Yahoo Stock API参数限制:
yahooStockPrices.getCurrentData()仅支持传入单个股票代码字符串,如果你传入数组也会触发调用失败,需要查询多个代码的话要循环调用接口。
修正后代码
const cheerio = require('cheerio'); const axios = require('axios'); const yahooStockPrices = require('yahoo-stock-prices'); // 爬取前10支S&P500股票代码 async function read_fortune_500() { const stockSymbols = [] try { const { data } = await axios({ method: "GET", url: "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies" }) const $ = cheerio.load(data) const elemSelector = '#constituents > tbody > tr > td:nth-child(1)' $(elemSelector).each((parentIndex, parentElem) => { if (parentIndex <= 9) { // 直接取单元格文本,去除多余空格 const symbol = $(parentElem).text().trim() if (symbol) { stockSymbols.push(symbol) } console.log('爬取到股票代码:', symbol) } }) } catch (err) { console.error('爬取失败:', err) } return stockSymbols; } // 批量获取股票数据 async function collect_stocks() { // 等待爬取完成拿到实际的股票代码数组 const symbols = await read_fortune_500() // 循环调用接口查询每支股票数据 for (const symbol of symbols) { try { // 注意:雅虎接口中带点的代码要替换为横杠,比如BRK.B需转为BRK-B const formatSymbol = symbol.replace('.', '-') const stockResult = await yahooStockPrices.getCurrentData(formatSymbol); console.log(`${symbol} 行情数据:`, stockResult); } catch (e) { console.error(`${symbol} 查询失败:`, e.message) } } } collect_stocks()
额外说明
如果只需要查询单支股票,不需要循环调用,直接取数组第一个元素传入接口即可。
内容的提问来源于stack exchange,提问作者Dave Michaels
相关产品推荐
相关产品推荐

