🎁 惊喜折扣:订阅享受 1折优惠!

⚡️ Nstproxy - 超过1.1亿IP地址,助力闪电般快速的数据抓取与自动化,起价仅需0.1美元/GB。

  • 价钱
  • 文档
ZH
联系

© 2025 NST LABS TECH LTD. ALL RIGHTS RESERVED

产品

指纹浏览器
Nstbrowser RPA
绕过Cloudflare
网页解锁器

解决方案

云端指纹浏览器
多账户管理
网页抓取&自动化
反机器人检测

资源

价格
下载
RPA 市场
联盟计划
合作伙伴
博客
版本更新

支持

联系

文档

法规

条款
隐私政策
Cookie 政策

产品解决方案资源支持法规

产品解决方案资源

支持法规

© 2025 NST LABS TECH LTD. ALL RIGHTS RESERVED

返回博客
雅虎财经网页抓取
Browserless

如何使用 Browserless 从雅虎财经抓取股票数据?

Yahoo Finance 是一个典型的动态网站,爬取它非常困难。本博客将帮助你轻松使用 Puppeteer 和 Browserless 完成 Yahoo Finance 网站爬取。
Oct 25, 2024Robin Brown

在雅虎财经上抓取数据合法吗?

关于从雅虎财经抓取数据的合法性,这是否会被认定为非法行为?

请别担心,雅虎财经网站上的大多数数据都是开源的,是公开信息。我们可以抓取的雅虎财经数据包括:

  • 股票市场新闻更新
  • 公司当前股价
  • 公司股价涨跌趋势
  • 共同基金和 ETF
  • 货币甚至加密货币的价值

尽管从原则上讲是正确的,但为了安全起见,您仍然需要注意当地的网络抓取法律和法规。

我们为什么要从雅虎财经抓取股票数据?

在抓取之前,确定原因很重要。我们为什么要抓取它?在这里,我们可以为您提供分析。

通过抓取最近的数据,投资者可以获得最新的股票价格、交易量和市场动态,从而做出及时的投资决策。此外,通过分析历史数据,投资者可以构建基本的模型来预测股价走势,并协助投资策略的制定。

我们总是害怕风险,可以通过获取不同股票的绩效数据,帮助我们优化投资组合,降低风险。

财务报告、新闻和其他事件对股价有重大影响。通过抓取数据,我们可以清楚地了解股票市场,帮助投资者做出正确的投资决策。

经过一个投资周期,我们需要对投资资金的进展情况进行反馈总结。使用 Browserless 进行数据抓取可以及时有效地测试历史数据,验证交易策略的有效性,从而提高交易成功率。

为什么 Browserless 在抓取雅虎财经方面帮助很大?

然而,雅虎财经可能会使用IP 阻断、验证码和请求速率限制等措施来阻止自动抓取。而且由于某些数据可能是通过 JavaScript 动态加载的,我们需要使用更强大、更稳定的程序来处理动态网页。

别难过!Browserless 擅长处理这些问题。

Browserless 是一个基于云的解决方案,专为可扩展的浏览器自动化、网络抓取和网络测试而设计。Browserless 与 Playwright 和 Puppeteer 具有原生兼容性。它还设计了自动验证码解决和代理服务。此外,它配备了一个可扩展的平台,通过 API 集成实时视图并检索日志和记录。

Browserless 现在完全可以免费测试!

您对网络抓取和 Browserless 有任何很棒的想法或疑问吗?
让我们看看其他开发人员在 Discord 上分享了什么!

使用 Puppeteer 和 Browserless 抓取雅虎财经

先决条件

我们需要 Browserless 服务来抓取雅虎财经。Nstbrowser 的 Browserless 是一款强大的工具,可以处理复杂的网络抓取和大规模自动化任务,并且支持完全托管的云部署。

Browserless 采用以浏览器为中心的方案,提供强大的无头部署功能,并提供更高的性能和可靠性。有关 Browserless 的更多信息,您可以从我们的 Browserless 文档 中学习。

  • 好吧,如何获得 API 密钥?请打开 Nstbrowser 客户端的 Browserless 菜单页面,或者您可以直接通过我们的 跳转链接 进行操作。
获取 API 密钥

构建一个爬取框架

  1. 安装 puppeteer。这里我们选择更轻量级的 puppeteer-core:
Bash Copy
# pnpm
pnpm i puppeteer-core
# yarn
yarn add puppeteer-core
# npm
npm i --save puppeteer-core
  1. 以下代码已在 Browserless 文档中为您准备好了。您只需要填写 apiKey 和 proxy 就可以开始后续的 Browserless 操作:
JavaScript Copy
import puppeteer from "puppeteer-core";

const apiKey = "your ApiKey"; // 必须填写
const config = {
    proxy: 'your proxy', // 必须填写;输入格式:schema://user:password@host:port 例如:http://user:password@localhost:8080
    // platform: 'windows', // 支持:windows、mac、linux
    // kernel: 'chromium', // 只支持:chromium
    // kernelMilestone: '128', // 支持:128
    // args: {
    //     "--proxy-bypass-list": "detect.nstbrowser.io"
    // }, // 浏览器参数
    // fingerprint: {
    //     userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent 自 v0.15.0 版本开始支持
    // },
};
const query = new URLSearchParams({
    token: apiKey, // 必须填写
    config: JSON.stringify(config),
});
const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;

开始爬取

步骤 1. 连接 Browserless 并爬取股价

在开始抓取雅虎财经之前,我们可以先观察一下雅虎财经的 URL:https://finance.yahoo.com/quote/AAPL/。其中,AAPL 是股票代码。

显然,您可以通过更改股票代码路径来切换到需要抓取的股票页面。然后打开开发者工具 (F12) 检查页面的 HTML 结构,并将光标定位到当前的市场价格。

接下来,我们将尝试抓取这个价格:

目标股价

在以上准备工作中,我们已经获得了 Browserless 连接端口,因此可以直接开始爬取。

JavaScript Copy
// 连接到 browserless
const browser = await puppeteer.connect({
  browserWSEndpoint: browserlessWSEndpoint,
  defaultViewport: null,
})

const page = await browser.newPage();
await page.goto('https://finance.yahoo.com/quote/AAPL');
// 添加截图,方便后续排查问题
await page.screenshot({ path: 'yahoo.png' });
const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
// 提取与选择器匹配的元素的内部文本(即股票价格)
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple 当前股价为:${regularMarketPrice}`);

步骤 2. 跳过 Cookie 授权

等等!如果我们现在运行上面的脚本,它很可能无法运行。为什么?让我们看看运行脚本时生成的截图 finance.png。

Cookie 授权

可以看出,爬取失败的原因是我们还没有进行 Cookie 授权。那么我们将使用 Puppeteer 来帮助我们跳过 Cookie 授权:

  • 打开一个新的浏览器重新触发 Cookie 授权页面
  • 使用开发控制台以相同的方式定位 接受全部 元素,并获得其对应的类选择器
  • 使用 puppeteer 点击该元素节点
跳过 Cookie 授权

以上操作只需几行简单的代码就能轻松完成!

以下代码用于等待页面上出现类名为 .consent-overlay 的元素,然后点击层中的 "接受全部" (.accept-all) 按钮。我们需要使用 try catch 来排除 Cookie 已授权的情况。

JavaScript Copy
try {
  await page.waitForSelector('.consent-overlay');
  // 点击 "接受全部" 按钮
  await page.click('.consent-overlay .accept-all');
} catch (e) {
  console.log('Cookie 已授权');
}
  • 因此代码应该为:
JavaScript Copy
import puppeteer from "puppeteer-core";

const apiKey = "your ApiKey"; // 'your proxy'
const config = {
  proxy: 'your proxy', // 必须填写;输入格式:schema://user:password@host:port 例如:http://user:password@localhost:8080
  // platform: 'windows', // 支持:windows、mac、linux
  // kernel: 'chromium', // 只支持:chromium
  // kernelMilestone: '128', // 支持:128
  // args: {
  //     "--proxy-bypass-list": "detect.nstbrowser.io"
  // }, // 浏览器参数
  // fingerprint: {
  //     userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent 自 v0.15.0 版本开始支持
  // },
};
const query = new URLSearchParams({
  token: apiKey, // 必须填写
  config: JSON.stringify(config),
});
const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;

const browser = await puppeteer.connect({
  browserWSEndpoint: browserlessWSEndpoint,
  defaultViewport: null,
})

const page = await browser.newPage();
await page.goto('https://finance.yahoo.com/quote/AAPL/');
await page.screenshot({ path: 'yahoo.png' });

try {
  await page.waitForSelector('.consent-overlay');
  // 点击 "接受全部" 按钮
  await page.click('.consent-overlay .accept-all');
} catch (e) {
  console.log('Cookie 已授权');
}

const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple 当前股价为:${regularMarketPrice}`);
  • 输出:
抓取输出

步骤 3. 完善脚本并使用股票代码作为脚本参数

但是,直接在代码中编写股票代码不够灵活。因此,我们最好在脚本顶部添加以下代码。以下代码将强制脚本使用脚本参数运行:股票代码。

JavaScript Copy
const tickerSymbols = process.argv.slice(2);

if (tickerSymbols.length === 0) {
  console.error('Ticker symbol CLI 参数缺失!');
  process.exit(2);
}

由于可能有多个股票代码,我们需要定义一个数组 (stockList) 来接收抓取的结果。在以下代码中,我们将使用简单的循环来遍历和处理传入的股票代码列表。

JavaScript Copy
// 包含所有抓取数据的数组
const stockList = [];

for (const tickerSymbol of tickerSymbols) {
  console.log(`正在抓取 ${tickerSymbol} 的数据`);

  // 导航到雅虎财经页面
  await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);

  try {
    await page.waitForSelector('.consent-overlay');
    // 点击 "接受全部" 按钮
    await page.click('.consent-overlay .accept-all');
  } catch (e) { }

  // 使用模板字面量和股票代码定义选择器
  const selectors = {
    regularMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="regularMarketPrice"]`,
    regularMarketChange: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChange"]`,
    regularMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChangePercent"]`,
    preMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="preMarketPrice"]`,
    preMarketChange: `[data-symbol="${tickerSymbol}"][data-field="preMarketChange"]`,
    preMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="preMarketChangePercent"]`
  };

  // 初始化一个空对象来存储财务数据
  const financialData = { tickerSymbol };

  // 循环遍历每个选择器以提取文本内容
  for (const [key, selector] of Object.entries(selectors)) {
    try {
      financialData[key] = await page.$eval(selector, el => el.innerText);

      // 删除百分比值的括号
      if (key.includes('ChangePercent')) {
        financialData[key] = financialData[key].replace('(', '').replace(')', '');
      }
    } catch {
      financialData[key] = 'N/A'; // 如果元素未找到,则将值设置为 N/A
    }
  }

  // 将当前股票代码的财务数据添加到股票数组中
  stockList.push(financialData);
}

console.log(JSON.stringify(stockList, null, 2));

运行以下脚本:

JavaScript Copy
node yahoo.mjs AAPL TSLA

如果成功,将在控制台中打印以下内容:

结果打印

步骤 4. 将数据导出到 CSV

显然,为了更好地进行数据分析,仅仅在控制台中打印数据是不够的。这里有一个简单的例子。只需手动拼接以下 CSV,然后使用 fs 模块创建抓取结果的 CSV 文件:

JavaScript Copy
// 生成 csv 字符串并写入 csv 文件
let csvData = 'Ticker Symbol,Regular Market Price,Regular Market Change,Regular Market Change Percent,Pre Market Price,Pre Market Change,Pre Market Change Percent\n';
stockList.forEach(stock => {
  csvData += `${stock.tickerSymbol},${stock.regularMarketPrice},${stock.regularMarketChange},${stock.regularMarketChangePercent},${stock.preMarketPrice},${stock.preMarketChange},${stock.preMarketChangePercent}\n`;
});
fs.writeFileSync('stocks_data.csv', csvData);
  • 完整代码:
JavaScript Copy
import puppeteer from "puppeteer-core";
import fs from 'fs'

const tickerSymbols = process.argv.slice(2);

if (tickerSymbols.length === 0) {
  console.error('Ticker symbol CLI 参数缺失!');
  process.exit(2);
}

const apiKey = "your ApiKey"; // 'your proxy'

const config = {
  proxy: 'your proxy', // 必须填写;输入格式:schema://user:password@host:port 例如:http://user:password@localhost:8080
  // platform: 'windows', // 支持:windows、mac、linux
  // kernel: 'chromium', // 只支持:chromium
  // kernelMilestone: '128', // 支持:128
  // args: {
  //     "--proxy-bypass-list": "detect.nstbrowser.io"
  // }, // 浏览器参数
  // fingerprint: {
  //     userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent 自 v0.15.0 版本开始支持
  // },
};

const query = new URLSearchParams({
  token: apiKey, // 必须填写
  config: JSON.stringify(config),
});

const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;

const browser = await puppeteer.connect({
  browserWSEndpoint: browserlessWSEndpoint,
  defaultViewport: null,
})
console.info('已连接!');

const page = await browser.newPage();

// 包含所有抓取数据的数组
const stockList = [];

for (const tickerSymbol of tickerSymbols) {
  console.log(`正在抓取 ${tickerSymbol} 的数据`);

  // 导航到雅虎财经页面
  await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);
  try {
    await page.waitForSelector('.consent-overlay');
    // 点击 "接受全部" 按钮
    await page.click('.consent-overlay .accept-all');
  } catch (e) { }

  // 使用模板字面量和股票代码定义选择器
  const selectors = {
    regularMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="regularMarketPrice"]`,
    regularMarketChange: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChange"]`,
    regularMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChangePercent"]`,
    preMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="preMarketPrice"]`,
    preMarketChange: `[data-symbol="${tickerSymbol}"][data-field="preMarketChange"]`,
    preMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="preMarketChangePercent"]`
  };

  // 初始化一个空对象来存储财务数据
  const financialData = { tickerSymbol };

  // 循环遍历每个选择器以提取文本内容
  for (const [key, selector] of Object.entries(selectors)) {
    try {
      financialData[key] = await page.$eval(selector, el => el.innerText);
      // 删除百分比值的括号
      if (key.includes('ChangePercent')) {
        financialData[key] = financialData[key].replace('(', '').replace(')', '');
      }
    } catch {
      financialData[key] = 'N/A'; // 如果元素未找到,则将值设置为 N/A
    }
  }

  // 将当前股票代码的财务数据添加到股票数组中
  stockList.push(financialData);
}

console.log(JSON.stringify(stockList, null, 2));

// 生成 csv 字符串并写入 csv 文件
let csvData = 'Ticker Symbol,Regular Market Price,Regular Market Change,Regular Market Change Percent,Pre Market Price,Pre Market Change,Pre Market Change Percent\n';
stockList.forEach(stock => {
  csvData += `${stock.tickerSymbol},${stock.regularMarketPrice},${stock.regularMarketChange},${stock.regularMarketChangePercent},${stock.preMarketPrice},${stock.preMarketChange},${stock.preMarketChangePercent}\n`;
});
fs.writeFileSync('stocks_data.csv', csvData);

await browser.close();

现在,运行脚本后,您不仅可以看到控制台打印,还可以看到在当前路径下写入的 stocks_data.csv 文件。

完整输出

检查 Browserless 仪表板

您可以在 Nstbrowser 客户端的 Browserless 菜单中查看最近请求的统计信息和剩余会话时间。

检查 Browserless 仪表板

结束语

Nstbrowser 的 Browserless 是一款功能强大的网络抓取和自动化工具。它可以轻松绕过检测并确保抓取股价时的稳定性。在本教程中,您学习了:

  • 为什么雅虎财经如此重要。
  • 如何使用 Puppeteer 和 Browserless 从中提取数据。

雅虎财经是一个典型的动态网站,基于 JavaScript 的强大功能,内置了高级数据保护技术。

因此,如果您想轻松地抓取雅虎财经数据,您必须使用同样强大的抓取工具。我们免费的 Browserless 为您提供了最方便、最快捷的抓取方式。只需调用几行代码,您就可以做到。

立即免费开始使用!

免责声明: 本文提到的任何数据和网站仅供演示之用。我们坚决反对任何非法和侵权行为。如果您有任何问题或疑虑,请立即与我们联系。

更多
HTTP/2绕过
Browserless
HTTP/2指纹识别是什么以及如何绕过它?
学习如何使用六种强大的方法绕过 Web 抓取中的 HTTP/2 指纹识别,从使用真实浏览器到基于云的 Browserless。躲避现代反机器人防御的检测。
Jun 03, 2025Carlos Rivera
在 Nstbrowser Docker 中加载浏览器扩展
Browserless
如何在 Nstbrowser Docker 中加载浏览器扩展?
学习在 Nstbrowser 中上传扩展的两种方法以及在 Docker 中启动它们的步骤。
Mar 19, 2025Carlos Rivera
在Docker中启动Nstbrowser配置文件
Browserless
如何在Docker中启动Nstbrowser配置文件?
学习如何在 Docker 中启动 Nstbrowser 配置文件,同步跨环境的数据,并使用 API 自动化工作流程。本指南涵盖从设置到执行的全部内容。
Mar 14, 2025Carlos Rivera
如何使用Nstbrowser的无头浏览器自动解决Cloudflare Turnstile (2025)
BrowserlessCloudflare BypassHeadless Browser
如何使用 Nstbrowser 的 Browserless 自动解决 Cloudflare Turnstile (2025)
学习如何使用Nstbrowser的无头浏览器服务和Puppeteer绕过Cloudflare Turnstile。本指南将引导您完成设置、实现以及在确保合规性和效率的同时自动化网页抓取任务的优势。
Mar 07, 2025Robin Brown
如何使用Nstbrowser的无头浏览器绕过Cloudflare 5s挑战(2025)
BrowserlessCloudflare Bypass
如何使用Nstbrowser的无头浏览器绕过Cloudflare 5s挑战(2025)
学习如何使用 Nstbrowser 的无浏览器服务和 Puppeteer 来绕过 Cloudflare 的 5s 挑战。本指南将引导您完成设置、实现以及在确保合规性和效率的同时自动化网页抓取任务的优势。
Mar 06, 2025Robin Brown
AI 驱动浏览器
Browserless
Browserless:最佳AI驱动浏览器,简化您的网络互动
本文探讨了AI代理与Browserless强大集成以简化和增强网页抓取的方式。
Jan 24, 2025Robin Brown
目录