# Yahoo Finance Scraper - Stock Quotes, Statistics & History (`rjmacarthy/yahoo-finance-scraper`) Actor

Scrape Yahoo Finance for any stock, ETF, index, crypto or FX ticker: live (delayed) quotes, P/E, EPS, dividends, earnings dates, key statistics and daily/weekly/monthly price history with dividends and splits. Raw numbers, cheap per-row pricing.

- **URL**: https://apify.com/rjmacarthy/yahoo-finance-scraper.md
- **Developed by:** [rj](https://apify.com/rjmacarthy) (community)
- **Categories:** Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ticker quotes

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Yahoo Finance Scraper - Stock Quotes, Key Statistics & Price History

Scrape **Yahoo Finance** for any ticker - US and international stocks, ETFs, indices (^GSPC), crypto (BTC-USD), currencies (EURUSD=X) and futures (GC=F). Get **quotes** (price, change, day and 52-week range, volume, market cap, beta, P/E, EPS, dividend, ex-dividend and earnings dates, analyst target), optional **key statistics** (valuation measures with 5 quarters of history, margins, returns, balance sheet, cash flow, short interest) and **price history** (daily, weekly or monthly OHLC, adjusted close, volume, dividends and splits). Every value is a **raw number**, not a "4.84T" string. Quotes, statistics and history all come from **one Actor**, and history is priced **per row at $0.0002**: a year of daily bars costs about $0.05, where per-item scrapers charge about $0.25. An incremental `sinceDate` option lets daily schedules append only new rows.

### What data can you get?

| Data | Mode | Fields |
|---|---|---|
| Quote | `quote` | price, change, changePercent, previousClose, open, dayLow/dayHigh, fiftyTwoWeekLow/High, volume, avgVolume3Month/10Day, bid/ask, pre/post-market price, marketCap, sharesOutstanding, beta, peTrailing/peForward, epsTrailing/epsForward, dividendRate, dividendYield, exDividendDate, dividendDate, earningsDate, targetMean/High/LowPrice, recommendation, analystCount, 50/200-day averages, all-time high/low |
| Company / instrument | `quote` | name, quoteType, exchange, currency, marketState, delayMinutes, sector, industry, website, country, employees |
| Fund / crypto / FX extras | `quote` | netAssets, navPrice, expenseRatio, ytdReturn, fundFamily, fundCategory, circulatingSupply, volume24Hr, fromCurrency/toCurrency |
| Key statistics (stocks) | `quote` + `includeStatistics` | enterpriseValue, trailing/forward P/E, PEG, price/sales, price/book, EV/revenue, EV/EBITDA, **valuationHistory** (5 quarters), profit/operating/gross/EBITDA margins, ROA, ROE, revenue, revenue per share, quarterly revenue and earnings growth, gross profit, EBITDA, net income, total cash/debt, debt/equity, current/quick ratio, book value per share, operating and free cash flow, 52-week change vs S\&P 500, float, insider/institutional holdings, shares short, short ratio, short % of float, dividend yields, payout ratio, last split |
| Price history | `history` | date, open, high, low, close, adjClose, volume, dividend, splitRatio, isDividend, isSplit, isComplete |

### Use cases

- **Portfolio and watchlist tracking** - pull prices, daily change and valuation for your holdings into Google Sheets every morning.
- **Stock screening and fundamental research** - compare P/E, PEG, margins, ROE, debt and short interest across a sector.
- **Backtesting and charting** - download 1, 5 or 10+ years of daily/weekly/monthly OHLC with adjusted closes, dividends and splits.
- **Dividend tracking** - dividend rate, yield, ex-dividend dates and the full dividend history per ticker.
- **Crypto and FX monitoring** - BTC-USD, ETH-USD, EURUSD=X and friends on a schedule.
- **Earnings calendars** - next earnings date and analyst targets for a list of tickers.
- **AI agents and dashboards** - clean, flat JSON with numbers as numbers.

### How to use

1. Enter your **tickers** exactly as Yahoo shows them (AAPL, BRK-B, ^GSPC, BTC-USD, EURUSD=X, 7203.T, VOD.L). Quote page URLs work too.
2. Pick **Quotes** or **Price history**.
3. Click **Start**. Download the results as JSON, CSV or Excel, or use the API.

**Quotes for a watchlist:**

```json
{ "tickers": ["AAPL", "MSFT", "NVDA", "TSLA", "SPY"], "mode": "quote" }
```

**Quotes with key statistics (stocks):**

```json
{ "tickers": ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN", "META", "TSLA"], "mode": "quote", "includeStatistics": true }
```

**One year of daily price history:**

```json
{ "tickers": ["SPY", "QQQ"], "mode": "history", "historyRange": "1y", "historyInterval": "daily" }
```

**Daily schedule that appends only new, finished bars:**

```json
{ "tickers": ["AAPL", "BTC-USD"], "mode": "history", "historyRange": "1mo", "historyInterval": "daily", "sinceDate": "3 days" }
```

With `sinceDate`, only bars dated after that day are output and the still-forming bar of today (or this week/month) is left out, so every row you get is final. A relative value such as `"3 days"` works on a schedule; overlapping days come back with the same `id` (`AAPL:1d:2026-11-03`), so de-duplicate on `id` when you append.

### Output example

A quote with merged key statistics (trimmed), from a real run:

```json
{
  "type": "quote",
  "id": "AAPL",
  "ticker": "AAPL",
  "symbol": "AAPL",
  "fundamentalsAvailable": true,
  "name": "Apple Inc.",
  "quoteType": "EQUITY",
  "exchange": "NMS",
  "exchangeName": "NasdaqGS",
  "currency": "USD",
  "marketState": "PRE",
  "delayMinutes": 15,
  "regularMarketTime": "2026-11-03T21:00:01.000Z",
  "price": 331.9,
  "change": -6.42001,
  "changePercent": -1.89762,
  "previousClose": 338.32,
  "open": 325.58,
  "dayLow": 325.33,
  "dayHigh": 334.5,
  "fiftyTwoWeekLow": 243.42,
  "fiftyTwoWeekHigh": 351.73,
  "volume": 61365001,
  "avgVolume3Month": 41614187,
  "preMarketPrice": 335.47,
  "postMarketPrice": 329.8248,
  "marketCap": 4843808227328,
  "sharesOutstanding": 14594180000,
  "beta": 1.089,
  "peTrailing": 36.95991,
  "peForward": 31.169645,
  "epsTrailing": 8.98,
  "epsForward": 10.64818,
  "dividendRate": 1.08,
  "dividendYield": 0.0033000002,
  "trailingAnnualDividendRate": 1.06,
  "trailingAnnualDividendYield": 0.0031331282,
  "exDividendDate": "2026-08-10",
  "dividendDate": "2026-08-13",
  "earningsDate": "2027-01-28T21:00:00.000Z",
  "earningsDateIsEstimate": true,
  "targetMeanPrice": 333.28052,
  "recommendation": "buy",
  "analystCount": 38,
  "fiftyDayAverage": 334.0514,
  "twoHundredDayAverage": 297.33844,
  "allTimeHigh": 351.73,
  "sector": "Technology",
  "industry": "Consumer Electronics",
  "statisticsStatus": "ok",
  "statistics": {
    "marketCap": 4843808227328,
    "enterpriseValue": 4846645673984,
    "trailingPE": 36.95991,
    "forwardPE": 31.169645,
    "pegRatio": 2.66,
    "priceToSales": 10.11584,
    "priceToBook": 43.031246,
    "enterpriseToRevenue": 10.122,
    "enterpriseToEbitda": 28.263,
    "fiscalYearEnd": "2026-09-26",
    "mostRecentQuarter": "2026-09-26",
    "profitMargin": 0.27604,
    "operatingMargin": 0.31125,
    "grossMargin": 0.48786,
    "valuationHistory": [
      {
        "date": "2026-06-30",
        "marketCap": 4249933332160,
        "enterpriseValue": 4266137332160,
        "trailingPE": 35.031477,
        "forwardPE": 30.394958,
        "pegRatio": 2.680994,
        "priceToSales": 9.510049,
        "priceToBook": 39.85541,
        "enterpriseToRevenue": 9.450023,
        "enterpriseToEbitda": 26.616779
      }
    ]
  },
  "url": "https://finance.yahoo.com/quote/AAPL/",
  "scrapedAt": "2026-11-04T12:30:03.300Z"
}
```

A price-history bar with a dividend:

```json
{
  "type": "bar",
  "id": "SPY:1d:2025-12-19",
  "ticker": "SPY",
  "interval": "1d",
  "currency": "USD",
  "exchange": "PCX",
  "date": "2025-12-19",
  "timestamp": "2025-12-19T14:30:00.000Z",
  "open": 676.59,
  "high": 681.09,
  "low": 676.47,
  "close": 680.59,
  "adjClose": 675.3154,
  "volume": 103599500,
  "dividend": 1.993,
  "splitRatio": null,
  "isDividend": true,
  "isSplit": false,
  "isComplete": true,
  "url": "https://finance.yahoo.com/quote/SPY/history/",
  "scrapedAt": "2026-11-04T12:29:45.527Z"
}
```

Missing values are `null` (keys are never omitted). If Yahoo ever serves a quote page without its fundamentals block, the item has `fundamentalsAvailable: false` and the run summary warns, instead of silently returning nulls. Ratios such as `dividendYield`, `profitMargin` and `heldPercentInstitutions` are fractions (0.0033 = 0.33%); `changePercent` is in percent (-1.9 = -1.9%). Dates are ISO (`2026-08-10`), times are ISO UTC. Bar `date` is the trading day in the exchange's time zone.

### Pricing

Pay per event - you only pay for what you get:

| Event | Price | When |
|---|---|---|
| `quote` | $0.001 | each ticker quote |
| `statistics` | $0.0005 | each stock whose key statistics were merged (only with `includeStatistics`) |
| `history-bar` | $0.0002 | each price-history row |

Examples: 1,000 quotes ≈ **$1.00**; 1,000 quotes with key statistics ≈ **$1.50**; 1 year of daily history for one ticker (~251 rows) ≈ **$0.05**; 1,000 history rows ≈ **$0.20**. Set **Maximum cost per run** in the run options: the Actor stops cleanly at your budget and never charges past it.

### Tips and limits

- **Data is delayed exactly as on Yahoo's site** (usually 15 minutes for US stocks, see `delayMinutes`). This is not a real-time feed.
- Key statistics exist for **stocks only**. ETFs, indices, crypto and currencies have no Key Statistics page; those tickers get `statistics: null`, `statisticsStatus: "not-applicable"` and no `statistics` charge. Fund facts (net assets, NAV, expense ratio, yield) are in the quote item.
- Yahoo's monthly history for some indices starts in 1985 even with `max`; daily history usually goes back further.
- `isComplete: false` marks today's (or this week's/month's) bar while the market is still trading. Its values will change.
- Unknown tickers are reported in the run log and `RUN_SUMMARY` (status `not-found`) and the run carries on.
- Requests are paced at about 1 per second (2 in parallel) to stay polite, so 100 tickers take about 2 minutes (double with key statistics).
- If you run from an EU IP or with an EU proxy, Yahoo may show a cookie-consent page. The Actor does not click through it: it reports it (status `consent`) and asks you to use a US/non-EU datacenter proxy.

### FAQ

**Is it legal to scrape Yahoo Finance?**
The Actor reads only public quote pages that anyone can open without logging in, and collects market data, not personal data. Yahoo's data is for research and personal use; you are responsible for complying with Yahoo's terms of service and the laws that apply to you, especially before redistributing data commercially.

**Does it use Yahoo's API?**
No. It reads the public HTML pages under `finance.yahoo.com/quote/...` and the data embedded in them, the same pages your browser loads. It does not call the query1/query2 API hosts.

**Do I need a proxy?**
Usually not. If Yahoo rate-limits the run (HTTP 429) or shows a consent page, enable Apify Proxy (datacenter). **Residential proxies are not supported:** if you select the RESIDENTIAL group, the Actor logs a warning and uses Apify datacenter proxy instead.

**Why is a field null?**
Yahoo does not publish it for that instrument (e.g. no P/E for a loss-making company, no dividend for non-payers, no sector for an index).

**Can I get intraday (1-minute/hourly) bars or options chains?**
Not in this version - daily, weekly and monthly bars only. Open an issue if you need them.

**Are the numbers adjusted for splits?**
`open/high/low/close` are split-adjusted as Yahoo shows them; `adjClose` is also adjusted for dividends.

### Integrations

- **API.** Start runs and fetch results with the [Apify API](https://docs.apify.com/api/v2), or the JavaScript and Python clients:

  ```bash
  curl -X POST "https://api.apify.com/v2/acts/rjmacarthy~yahoo-finance-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"tickers":["AAPL","MSFT"],"mode":"quote"}'
  ```

- **Schedules + webhooks.** Run every trading day and trigger your pipeline when it finishes.

- **Zapier, Make, n8n.** Push prices into Google Sheets, Airtable, Slack or e-mail with no code.

- **Google Sheets, Airbyte, Keboola and more** through Apify integrations.

- **AI agents.** Use the Actor as a tool through the Apify MCP server.

### Changelog

- **0.1** (November 2026) - First release: quotes, key statistics with valuation history, daily/weekly/monthly price history with dividends and splits, incremental `sinceDate`.

### Ready-to-run examples

- [Get Magnificent 7 stock quotes and key statistics](https://apify.com/rjmacarthy/yahoo-finance-scraper/examples/magnificent-7-stock-quotes-key-statistics)
- [Download 1 month of daily SPY and QQQ price history](https://apify.com/rjmacarthy/yahoo-finance-scraper/examples/spy-qqq-daily-price-history-1-month)

### More scrapers by the same developer

- [Apple App Store Scraper: Apps, Search & Reviews](https://apify.com/rjmacarthy/app-store-scraper)
- [ESPN Scraper - Scores, Odds, Standings & Tennis](https://apify.com/rjmacarthy/espn-scraper)
- [Google Play Scraper: Apps, Search & Reviews](https://apify.com/rjmacarthy/google-play-scraper)
- [PDF to Markdown & Text Converter for LLMs and RAG](https://apify.com/rjmacarthy/pdf-to-markdown)
- [Roblox Games Scraper - Players, Visits, Charts & Stats](https://apify.com/rjmacarthy/roblox-games-scraper)
- [Telegram Channel Scraper](https://apify.com/rjmacarthy/telegram-channel-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

### Support

Found a ticker that doesn't work, or need an extra field? Open an issue on the **Issues** tab with your input. Fixes are usually quick.

# Actor input Schema

## `tickers` (type: `array`):

Yahoo Finance symbols, exactly as shown on finance.yahoo.com: stocks (AAPL, BRK-B, 7203.T, VOD.L), ETFs (SPY), indices (^GSPC, ^IXIC), crypto (BTC-USD), currencies (EURUSD=X) and futures (GC=F). Quote page URLs work too. Max 200 per run.

## `mode` (type: `string`):

"Quotes" gives one item per ticker (price, change, ranges, volume, market cap, P/E, EPS, dividend, earnings date, analyst target...). "Price history" gives one item per daily/weekly/monthly bar (open, high, low, close, adjusted close, volume, dividends and splits).

## `includeStatistics` (type: `boolean`):

Quotes mode: also open each stock's Key Statistics page and merge valuation measures (incl. 5 quarters of history), margins, returns, income, balance sheet, cash flow, share/short-interest stats and dividend/split facts into the item. One extra page per stock, charged as the "statistics" event. Skipped (and not charged) for ETFs, indices, crypto and currencies, which have no such page.

## `historyRange` (type: `string`):

Price history mode: how far back to go.

## `historyInterval` (type: `string`):

Price history mode: one row per trading day, week or month.

## `sinceDate` (type: `string`):

Price history mode: only output bars dated AFTER this day, e.g. 2026-10-01, or a relative period such as "3 days" or "2 weeks". When set, the still-forming bar of the current day/week/month is left out, so a daily schedule with "3 days" appends only finished rows (de-duplicate on the item "id" if periods overlap). Leave empty for the full range.

## `maxItems` (type: `integer`):

Maximum number of dataset items for the whole run (quotes or price rows). In history mode the most recent bars are kept. 0 = no limit. The default fits 5 tickers x 1 year of daily bars.

## `proxyConfiguration` (type: `object`):

Not needed normally. Enable Apify Proxy (datacenter) if Yahoo rate-limits the run or shows a cookie-consent page (EU IPs). Residential proxies are not supported: if selected, the Actor falls back to Apify datacenter proxy.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "MSFT",
    "NVDA",
    "TSLA",
    "SPY"
  ],
  "mode": "quote",
  "includeStatistics": false,
  "historyRange": "1y",
  "historyInterval": "daily",
  "maxItems": 2000,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `quotes` (type: `string`):

One row per ticker: price, change, ranges, volume, market cap, P/E, EPS, dividend yield and earnings date.

## `statistics` (type: `string`):

Quotes with merged key statistics: valuation, margins, returns, cash, debt and short interest.

## `history` (type: `string`):

One row per daily/weekly/monthly bar: OHLC, adjusted close, volume, dividends and splits.

## `allFields` (type: `string`):

Every field of every item, including the full statistics object and valuation history.

## `summary` (type: `string`):

Per-ticker status, counts, request statistics and warnings.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tickers": [
        "AAPL",
        "MSFT",
        "NVDA",
        "TSLA",
        "SPY"
    ],
    "mode": "quote"
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/yahoo-finance-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "tickers": [
        "AAPL",
        "MSFT",
        "NVDA",
        "TSLA",
        "SPY",
    ],
    "mode": "quote",
}

# Run the Actor and wait for it to finish
run = client.actor("rjmacarthy/yahoo-finance-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tickers": [
    "AAPL",
    "MSFT",
    "NVDA",
    "TSLA",
    "SPY"
  ],
  "mode": "quote"
}' |
apify call rjmacarthy/yahoo-finance-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rjmacarthy/yahoo-finance-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/2rbIpYHtyXoH9drEo/builds/mMeLdKd2O0BbFXdA9/openapi.json
