Yahoo Finance Quote Scraper
Pricing
from $1.25 / 1,000 results
Yahoo Finance Quote Scraper
Scrape Yahoo Finance quotes by ticker: price, change and changePercent, previousClose, day range, 52-week range, marketCap as an exact 4449911701504 rather than 4.45T, peRatio, eps, volume, dividendYield, beta, currency and exchange. Equities, ETFs, indices and futures. No API key or session crumb.
What does the Yahoo Finance Quote Scraper do?
Hand this Actor a list of ticker symbols and it returns a row per symbol holding the current quote:
price, change and change percent, previous close, the day range, the 52-week range, market cap, PE
ratio, EPS, volume, dividend yield, beta, currency and exchange. Every measure is a number, so
marketCap is 4449911701504 rather than the "4.45T" the page prints.
It works on more than US equities. Suffixed foreign listings (SHEL.L, 7203.T), class shares
(BRK-B), indices (^GSPC) and futures (CL=F) all resolve, because the input takes whatever
symbol Yahoo Finance itself uses.
- Exact numbers throughout: market cap, volume, EPS, both ranges
changePercentanddividendYieldare always in percent, never a fraction- An absent measure is
null, never0, so a company with no trailing earnings does not read as a PE of zero - Up to 200 tickers per run, fetched in parallel
- No Yahoo account, API key or session crumb
What data does it extract?
| Field | Type | Description |
|---|---|---|
ticker | string | The symbol as Yahoo records it, upper-cased, e.g. AAPL |
name | string | Company or fund name, e.g. Apple Inc. |
price | number | Regular-market price |
currency | string | e.g. USD |
change | number | Absolute move, full precision |
changePercent | number | In percent: a -1.09% move is -1.0867469 |
previousClose | number | Previous session close |
dayLow | number | Session low |
dayHigh | number | Session high |
fiftyTwoWeekLow | number | 52-week low |
fiftyTwoWeekHigh | number | 52-week high |
marketCap | number | Exact, e.g. 4449911701504, where the page shows "4.45T" |
peRatio | number | Trailing PE. null for a company with no trailing earnings |
eps | number | Trailing EPS, negative where the company is loss-making |
volume | number | e.g. 34168163, where the page shows "34.17M" |
dividendYield | number | In percent, so 0.35% is 0.35. Falls back to a fund's distribution yield |
beta | number | Falls back to a fund's 3-year beta where no plain beta is published |
exchange | string | e.g. NasdaqGS |
sourceUrl | string | The quote page the row was read from |
collectedAt | string | ISO timestamp of the fetch |
Why scrape Yahoo Finance?
Usually because a market data subscription is hard to justify for a job that runs twice a day. Refreshing a watchlist, screening a few hundred names on PE and dividend yield, or checking how far a holding sits from its 52-week high are all one-row-per-ticker problems, and this returns exactly that.
A few things it handles that the free APIs tend not to. One input can mix AAPL, SHEL.L, 7203.T
and ^GSPC without any per-market special-casing. fiftyTwoWeekLow and fiftyTwoWeekHigh arrive
next to price, so range rules are a one-line calculation rather than a second call. And a morning
run over a ticker list gives you changePercent for every name at once, which is enough to drive
alerts.
How to use it
- Use Try for free on this page, or add the Actor to your Apify account.
- Enter your symbols in the Tickers field, one per line. Case does not matter;
aaplandAAPLcollapse to a single fetch. - Raise Concurrency for a long ticker list. The default of 5 is comfortable for a few dozen.
- Set Maximum results if you want a ceiling on the dataset.
- Click Start, then export from the Dataset tab as JSON, CSV or Excel.
- Any symbol that could not be read is listed in the run's
SUMMARYrecord with its error.
Note that the input takes symbols, not Yahoo Finance URLs. If you have a URL, the symbol is the
segment after /quote/.
Input
| Field | Type | Default | Description |
|---|---|---|---|
tickers | array of strings | required | Yahoo Finance symbols. Between 1 and 200 entries. Upper-cased and de-duplicated before fetching |
maxItems | integer | 1000 | Ceiling on dataset rows, 1 to 50000 |
concurrency | integer | 5 | Tickers fetched in parallel, 1 to 10 |
{"tickers": ["AAPL", "MSFT", "BRK-B", "^GSPC", "SHEL.L", "CL=F"],"maxItems": 1000,"concurrency": 5}
Symbols are validated against the character set Yahoo builds them from before anything is fetched, so a stray URL or a pasted sentence is rejected up front rather than turned into a request.
Output
One row per ticker. The shape below is illustrative — it shows the fields and their types, not a captured run.
{"ticker": "AAPL","name": "Apple Inc.","price": 304.91,"currency": "USD","change": -3.350006,"changePercent": -1.0867469,"previousClose": 308.26,"dayLow": 303.12,"dayHigh": 309.44,"fiftyTwoWeekLow": 195.27,"fiftyTwoWeekHigh": 312.8,"marketCap": 4449911701504,"peRatio": 38.42,"eps": 7.94,"volume": 34168163,"dividendYield": 0.35,"beta": 1.09,"exchange": "NasdaqGS","sourceUrl": "https://finance.yahoo.com/quote/AAPL/","collectedAt": "2026-08-21T09:14:03.512Z"}
How it reads exact numbers
The quote page is a SvelteKit app that inlines the JSON responses of the API calls it made, so the
whole quote is already sitting in the HTML as exact numbers, with 4449911701504 next to the
"4.45T" that gets rendered. The Actor reads that embedded quoteSummary payload directly. There
is no model-backed extraction anywhere in the path and no display string to unpick.
Requesting the same payload from query1.finance.yahoo.com is not an option: it answers
Invalid Crumb without the per-session crumb and cookie pair the page holds. Reading the response
Yahoo already embedded avoids having to acquire one.
Reliability
Because every field comes out of the payload Yahoo itself embedded, a value is either present and
exact or absent. Yahoo wraps each measure as { raw, fmt } and degrades an absent one to an empty
object rather than to zero, which the Actor preserves as null. A missing PE ratio therefore comes
back as null, never as a misleading 0 that would ruin a screen.
Percentages get the same care. Yahoo stores them as fractions and renders them with a % suffix, so
the suffix on its own formatted value is what says which unit raw is in. Conversion happens only
where that suffix is present, which is why changePercent and dividendYield are consistently in
percent rather than one of each.
A ticker whose page carries no regular-market price is recorded under failures in the run's
SUMMARY rather than emitted as an empty row, and a run in which every ticker failed exits with an
error.
There are no retries. The String Unblocker behind this Actor owns proxy rotation and solver selection, so a retry loop out here would re-roll the same block.
Limitations
Current quote data only. No historical price series, no options chains, no analyst estimates, no
financial statements, no news, and no ticker search or screening — you supply the symbols. Values
reflect what Yahoo Finance was showing at the moment of collection, stamped in collectedAt, and
are delayed or stale exactly as Yahoo's own page is for that exchange. Fields Yahoo does not publish
for a given instrument, such as a PE ratio for a loss-making company or a dividend yield for a
non-payer, come back as null.
How much does it cost?
Pricing is per event: one charge for each quote row written to the dataset. A ticker that fails produces no row and costs nothing. The current rate is in the pricing panel at the top of this page.
Runs started from an Apify free plan stop at 250 requests and 250 results, reported in the run's
status message. The tickers input already caps at 200, so in practice a free-plan run is bounded
by that ceiling rather than by the 250 limit. Any paid plan runs the full input and whatever
maxItems you set. The cap exists because this Actor fetches through String's own infrastructure,
which Apify does not reimburse on free-plan runs.
Using it with the Apify API
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });const run = await client.actor("usestring/yahoo-finance-quotes").call({tickers: ["AAPL", "MSFT", "NVDA", "^GSPC"],concurrency: 5});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const quote of items) {const offHigh = (1 - quote.price / quote.fiftyTwoWeekHigh) * 100;console.log(quote.ticker, quote.price, `${offHigh.toFixed(1)}% off 52w high`);}const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord("SUMMARY");console.log(summary?.value);
Is it legal to scrape Yahoo Finance?
The Actor reads the public quote page any logged-out visitor can open. No account, no API key, no session crumb, no paywall. Reading an open page is not unauthorised access under US or EU law, and this Actor does nothing to reach past what the page already serves.
Quote rows are facts about instruments, not personal data, so the privacy questions that follow people-data scraping do not arise here. Market data does carry redistribution terms from the exchanges that originate it, so read it, analyse it and act on it, but do not resell it as a feed. Nothing here is legal or investment advice, and delayed quotes should not be treated as a trading source of truth.
Related actors
- G2 Reviews Scraper — what customers say about a listed software vendor, which is the qualitative half of the same research.
- Capterra Reviews Scraper — 25 reviews per product with ease of use, customer service and value for money scored separately.
- Glassdoor Jobs Scraper — hiring volume and pay bands, a workable proxy for whether a company is expanding.
- LinkedIn Profile Scraper — public profiles of the
people running the business, by slug or
/in/URL.
FAQ
Do I need a Yahoo Finance account, API key or crumb? No. The Actor reads the quote data Yahoo Finance already embeds in its own public quote page, so there is no login, no API key and no per-session crumb to obtain.
Is the market cap a number or a display string?
A number. marketCap comes back as an exact integer such as 4449911701504 where the page renders
"4.45T". Price, volume, EPS and both ranges are numbers too.
What ticker formats does the input accept?
Plain US symbols (AAPL), class shares (BRK-B), suffixed foreign listings (SHEL.L, 7203.T),
indices (^GSPC) and futures (CL=F). Symbols only — not Yahoo Finance URLs.
How many tickers can one run collect?
Up to 200, which is the ceiling on the tickers input. Each ticker is one request and one row.
Is changePercent a fraction or a percentage?
A percentage. A -1.09% move is -1.0867469, not -0.010867469. dividendYield follows the same
convention, so 0.35% is 0.35.
Does it return historical prices, options chains, news or financial statements? No. Each row is the current quote summary for one ticker and nothing further.
How delayed are the prices?
Exactly as delayed as Yahoo's own public page is for that exchange, since the Actor reads what that
page carries. collectedAt records when the fetch happened, not when the exchange published the
tick.
What happens if a ticker does not exist?
Its page carries no regular-market price, so it is recorded under failures in the run's SUMMARY
and the rest of the batch still returns.
Feedback
If a symbol fails or a field looks wrong, open an issue from the Issues tab on this Actor's Store page and include the ticker that reproduces it.