Scrape Finviz (finviz.com) into clean JSON or CSV. It runs the stock and ETF screener with any of Finviz's filters, signals and sort orders, and returns every column as typed numbers: valuation, growth, margins, ownership, short interest, performance and technicals, over 100 fields per stock. It also reads full quote pages: the snapshot metrics, company profile, analyst upgrades and price targets, news headlines, insider trades, top institutional holders, financial highlights and revenue by segment. Add the site-wide latest insider trading feed, sector and industry performance, and the earnings, ex-dividend and economic calendars. It's built for stock screening pipelines, quant research, watchlist dashboards, earnings-season tooling and fundamentals datasets, and ships as a CLI and a Python library.
Powered by ScrapeUnblocker. Every page is fetched through the ScrapeUnblocker getPageSource API, so you don't have to handle blocks, rate limits or proxies yourself.
finviz-scraper screen cap_largeover fa_pe_u20 fa_div_o3 --order -dividend_yield_pct -f table
finviz-scraper screen --signal ta_unusualvolume --limit 20 -f table
finviz-scraper screen --etf fa_div_o3 --order -assets_under_management -f csv -o etfs.csv
finviz-scraper filters --search dividend -f table
finviz-scraper quote AAPL MSFT NVDA -f csv -o quotes.csv
finviz-scraper insider --type buy --min-value 1000000 --sort -value -f table
finviz-scraper groups --group industry --sector technology --order -perf_ytd_pct -f table
finviz-scraper earnings --from 2026-10-26 --to 2026-10-30 -f table
finviz-scraper economic --importance 3 -f table- Stock screener (
screen): any combination of Finviz filter tokens (cap_largeover,fa_pe_u20,sec_technology,ta_rsi_os30, ...), a signal (top gainers, new highs, unusual volume, upgrades, insider buying, ...), a ticker list, and sorting by any field, descending or ascending. The defaultallview returns every column for each stock: price, change, gap, volume and relative volume; market cap and enterprise value; P/E, forward P/E, PEG, P/S, P/B, P/FCF, EV/EBITDA, EV/Sales; EPS and sales growth (this year, next year, past 3/5 years, next 5 years, quarter over quarter, TTM) and the last earnings surprise; gross, operating and net margins; ROA, ROE, ROIC; debt ratios; dividend, yield, payout and dividend growth; shares outstanding and float; insider and institutional ownership and transactions; short float, short ratio and short interest; performance from one week to ten years; beta, ATR, volatility, RSI, SMA20/50/200 distance, distance from 50-day, 52-week and all-time highs and lows; analyst recommendation and target price; earnings, IPO and ex-dividend dates; and the latest headline. It pages through results 20 at a time up to--limit(or--all), with duplicates removed. - ETF screener (
screen --etf): the same filters plus ETF columns: category, asset type, tags, expense ratio, number of holdings, assets under management, net fund flows (1 month, 3 months, YTD) and 1/3/5-year returns. - Filter discovery (
filters): every screener filter with its category, description and all of its tokens with labels, Elite-only options marked.--key fa_pelists one filter's tokens;--search dividendfinds filters by name. - Ignored-filter warnings: Finviz silently drops filters it doesn't know and ignores values that aren't one of a filter's options (such as Elite-only custom ranges). The scraper checks what Finviz applied and warns about every filter, signal or sort it ignored, so a typo can't quietly widen your screen.
- Quote pages (
quote): price, change and after-hours/pre-market price; sector, industry, country, exchange and their screener filter tokens; company description and website; about 90 snapshot metrics as numbers (the same field names as the screener, plus next year's EPS estimate, dividend TTM, the next earnings date and whether it is before the open or after the close); analyst ratings (date, action, firm, rating from/to, price target from/to); news (time, headline, source, link); the stock's insider trades with SEC Form 4 links; top institutional holders (fund managers and funds, % owned); financial highlights (annual and quarterly EPS, revenue, shares outstanding); the income statement summary; and revenue by product, region and segment. ETF quote pages add category, sponsor, expense ratio, AUM, holdings, returns, flows, tags and (with--fund-flows) the daily AUM and flow history. - News and ratings (
news,ratings): just a ticker's headlines or analyst actions, for one or many tickers. - Insider trading (
insider): the latest SEC Form 4 transactions across all stocks: ticker, company, industry, owner, relationship, date, transaction type, price, shares, value, shares held afterwards, filing time and the SEC filing link. Filter by buys or sales, by insiders vs. 10% owners and by minimum value, and sort by value, shares, date or filing time.--tickergives one stock's insider trades. - Groups (
groups): sectors, industries (all, or one sector's), countries or market-cap classes with every column (stock count, market cap, P/E, forward P/E, PEG, P/S, P/B, dividend yield, growth, margins, ROE, debt, short float, recommendation, volume and performance from week to year), each with the screener filter token for that group. - Earnings calendar (
earnings): companies reporting each day with timing (before the open / after the close), market cap, EPS and sales estimates, and once reported the actuals, surprises and next-day price reaction. Largest companies first by default. - Dividend calendar (
dividends): ex-dividend dates with the dividend amount, special dividend, yield and market cap. - Economic calendar (
economic): releases such as CPI, payrolls, GDP, PCE and Fed decisions, with importance (1-3), the period they cover, actual, forecast and previous values. - Robust: retries with backoff on timeouts, transient errors and incomplete pages, and raises
NotFoundErrorfor unknown tickers. - Output as JSON, JSON Lines, CSV or a terminal table; plain dicts and typed dataclasses in Python. Money and share counts are whole numbers (dollars and shares, not millions);
*_pctfields are percentages.
Finviz's screener pages carry their data as JSON inside the page: typed numbers for every column of the 20 rows shown, the total match count, and the definition of every filter with its options. The scraper reads that JSON instead of the HTML table, so you get exact numbers (not display strings like 5074.76B). The all view asks Finviz for every column at once, so one request returns everything about 20 stocks.
Finviz echoes back the filters, signal and sort it applied. The scraper compares that and the page's filter definitions with what you asked for, which is how it spots filters Finviz dropped or ignored.
Quote, insider and group pages are server-rendered HTML tables, read with BeautifulSoup by header label, not by position. Snapshot values such as 5074.76B, 1.10 (0.32%) and 348.36 -0.18% become numbers, and dates such as Oct-20-26 or Nov 02 AMC become ISO dates. Quote pages also embed JSON for the financial highlights, income statement, institutional holders and ETF fund flows. The calendars come from the JSON Finviz's own calendar pages load.
Each page or JSON response is one request to ScrapeUnblocker's getPageSource endpoint; no browser rendering is needed.
git clone https://github.com/ScrapeUnblocker/finviz-scraper.git
cd finviz-scraper
python -m pip install .Get an API key at scrapeunblocker.com and expose it as SCRAPEUNBLOCKER_KEY (see .env.example):
export SCRAPEUNBLOCKER_KEY=your_key_hereRequires Python 3.9+. Runtime dependencies are the official scrapeunblocker SDK and beautifulsoup4.
finviz-scraper [--proxy-country CC] [--retries 3] [-v] COMMAND ...
screen [FILTER ...] [--signal S] [--order FIELD] [--tickers A,B,...]
[--view all|overview|valuation|ownership|performance|financial|technical]
[--etf] [--limit N | --all] [--columns a,b,...]
filters [--etf] [--key KEY] [--search TEXT]
quote TICKER ... [--fund-flows]
news TICKER ...
ratings TICKER ...
insider [--type all|buy|sale] [--owners all|insiders|ten-percent] [--min-value N]
[--sort filed|date|value|shares|price|ticker|shares-total] [--ticker T] [--limit N]
groups [--group sector|industry|country|capitalization] [--sector SECTOR] [--order FIELD]
earnings [--from DATE] [--to DATE] [--sort market-cap|time|ticker] [--pages N | --all]
dividends [--from DATE] [--to DATE]
economic [--from DATE] [--to DATE] [--importance 1|2|3]
every command: [-f json|jsonl|csv|table] [-o FILE]
Filters are Finviz's own tokens: the ones in a Finviz screener URL after f=. Run finviz-scraper filters -f table to list every filter, and finviz-scraper filters --key <key> -f table for its tokens. Some common ones:
| Token | Meaning | Token | Meaning |
|---|---|---|---|
cap_mega, cap_largeover, cap_smallunder |
market cap class | sec_technology, sec_healthcare |
sector |
ind_semiconductors |
industry | geo_usa, geo_europe |
country / region |
idx_sp500, idx_ndx |
index member | exch_nasd, exch_nyse |
exchange |
fa_pe_u20, fa_pe_profitable |
P/E | fa_fpe_u15 |
forward P/E |
fa_div_o3, fa_div_pos |
dividend yield | fa_roe_o20 |
return on equity |
fa_epsyoy1_o10 |
EPS growth next year | fa_salesqoq_o20 |
sales growth Q/Q |
sh_avgvol_o1000 |
average volume over 1M | sh_price_10to50 |
price $10-50 |
sh_short_o20 |
short float over 20% | sh_insidertrans_pos |
insider buying |
an_recom_buybetter |
analyst Buy or better | earningsdate_thisweek |
reports this week |
ta_rsi_os30 |
RSI oversold (<30) | ta_sma200_pa |
price above SMA200 |
ta_highlow52w_nh |
new 52-week high | ta_perf_ytdup |
up year to date |
A filter only takes the values in its option list. Custom ranges such as fa_pe_5to30 are a Finviz Elite feature (the Custom option, marked Elite-only in filters), so Finviz ignores them for everyone else and the scraper warns about them.
Signals (--signal): ta_topgainers, ta_toplosers, ta_newhigh, ta_newlow, ta_mostvolatile, ta_mostactive, ta_unusualvolume, ta_overbought, ta_oversold, n_upgrades, n_downgrades, n_earningsbefore, n_earningsafter, it_latestbuys, it_latestsales, n_majornews. Chart patterns (wedges, channels, double tops, ...) are the ta_pattern filter.
Sorting (--order): any output field name, - first for descending: --order -market_cap, --order pe, --order -perf_ytd_pct, --order -short_float_pct, --order -assets_under_management (ETFs). Group tables also sort by stocks and name.
| Option | Meaning |
|---|---|
screen --view |
all (default) returns every column. The named Finviz views return fewer columns for the same one request per 20 rows. |
screen --columns |
Keep only these fields in the output (any format), e.g. ticker,pe,roe_pct. |
screen --limit / --all |
Rows to collect (default 100), or every match. |
insider --owners |
insiders leaves out 10% owners, ten-percent keeps only them. |
groups --sector |
With --group industry: only that sector's industries, e.g. technology, healthcare, financial, consumercyclical. |
earnings --pages |
Pages of 50 companies per day (default 1: the 50 largest by market cap); --all for every company. Weekends are skipped. |
--from / --to |
YYYY-MM-DD, today or tomorrow. Defaults: today and the 6 days after. Up to 92 days. |
Requests per command:
| Command | Requests |
|---|---|
screen |
1 per 20 rows |
filters, insider, groups |
1 |
quote, news, ratings |
1 per ticker |
earnings |
1 per weekday per 50 companies |
dividends |
1 per weekday (more on days with over 50 ex-dates) |
economic |
1 per calendar week |
from finviz_scraper import FinvizScraper
fz = FinvizScraper() # reads SCRAPEUNBLOCKER_KEY
# Large caps under 20x earnings with a 3%+ yield, highest yield first
result = fz.screen(
["cap_largeover", "fa_pe_u20", "fa_div_o3"], order="-dividend_yield_pct", limit=50
)
print(result.total, result.ignored) # matches, and anything Finviz did not apply
for row in result.rows[:5]:
print(row["ticker"], row["dividend_yield_pct"], row["payout_ratio_pct"], row["pe"])
# Every metric for a watchlist in one request
watch = fz.screen(tickers=["AAPL", "MSFT", "NVDA", "GOOGL"]).rows
# Biggest ETFs paying over 3%
etfs = fz.screen(["fa_div_o3"], etf=True, order="-assets_under_management", limit=20).rows
# One stock in depth
quote = fz.quote("AAPL")
quote.metrics["forward_pe"], quote.metrics["target_price"], quote.metrics["earnings_date"]
[(r.date, r.analyst, r.rating, r.price_target_to) for r in quote.ratings[:3]]
[(n.published, n.source, n.title) for n in quote.news[:5]]
# Insider buying worth $1M+, sectors by YTD performance, next week's events
buys = fz.insider("buy", min_value=1_000_000, sort="-value")
sectors = fz.groups("sector", order="-perf_ytd_pct")
reports = fz.earnings("2026-10-26", "2026-10-30")
releases = fz.economic("2026-10-26", "2026-10-30", min_importance=3)
# Discover filters
[o.token for o in next(f for f in fz.filters() if f.key == "fa_pe").options]screen() returns a ScreenResult (rows as dicts, total, applied_filters, ignored, url). quote() returns a Quote; insider(), earnings(), dividends() and economic() return lists of InsiderTrade, EarningsEvent, DividendEvent and EconomicEvent; groups() returns dicts. Every dataclass has to_dict(), and finviz_scraper.export.write() saves any of them as JSON, JSONL or CSV.
finviz-scraper screen cap_largeover fa_pe_u20 --order -market_cap --limit 6 -f table:
rank ticker company sector market_cap pe price change_pct volume
1 GOOGL Alphabet Inc Communication Services 3.90T 16.09 320.21 -1.24 17.57M
2 GOOG Alphabet Inc Communication Services 3.90T 15.94 317.28 -1.08 10.86M
3 AMZN Amazon.com Inc Consumer Cyclical 2.68T 19.95 248 -0.95 25.57M
4 BRK-B Berkshire Hathaway Inc Financial 1.16T 13.63 542.19 -0.87 4.31M
5 BRK-A Berkshire Hathaway Inc Financial 1.16T 13.64 813595 -0.84 373
6 SKHY SK Hynix Inc ADR Technology 998.69B 8.90 137.02 4.05 16.31M
finviz-scraper insider --type buy --min-value 1000000 --sort -value -n 4 -f table:
date ticker owner relationship transaction price value
2026-10-15 CRBG NIPPON LIFE INSURANCE CO 10% Owner Buy 33.43 17.08M
2026-10-16 CRBG NIPPON LIFE INSURANCE CO 10% Owner Buy 34.71 12.05M
2026-10-21 CRBG NIPPON LIFE INSURANCE CO 10% Owner Buy 35.38 7.68M
2026-10-21 DOLE Pale Fire Capital SE 10% Owner Buy 13.12 5.76M
finviz-scraper economic --from 2026-10-26 --to 2026-10-30 --importance 3 -f table:
date time imp event period actual forecast previous
2026-10-27 08:30 *** Durable Goods Orders MoM Sep 0.6% 0%
2026-10-28 14:00 *** Fed Interest Rate Decision 4.0% 4%
2026-10-28 14:30 *** Fed Press Conference
2026-10-29 08:30 *** Core PCE Price Index MoM Sep 0.3% 0.2%
2026-10-29 08:30 *** GDP Growth Rate QoQ Adv Q3 3% 2.2%
finviz-scraper quote MSFT (trimmed; the full output has about 90 metrics, up to 100 headlines, the latest analyst ratings, insider trades, holders and financials):
{
"ticker": "MSFT",
"company": "Microsoft Corp",
"is_etf": false,
"sector": "Technology",
"industry": "Software - Infrastructure",
"country": "USA",
"exchange": "NASD",
"price": 524.51,
"change_pct": 0.66,
"extended_price": 524.92,
"extended_label": "Aftermarket Close",
"metrics": {
"market_cap": 3895230000000,
"pe": 29.23,
"forward_pe": 22.29,
"peg": 1.2,
"eps_ttm": 17.95,
"eps_next_year_estimate": 23.53,
"eps_growth_next_5y_pct": 18.6,
"roe_pct": 34.04,
"dividend_yield_pct": 0.75,
"short_float_pct": 0.84,
"target_price": 597.34,
"analyst_recommendation": 1.24,
"from_52w_high_pct": -5.28,
"rsi_14": 52.61,
"earnings_date": "2026-10-28",
"earnings_timing": "after_close"
},
"ratings": [
{
"date": "2026-10-05",
"action": "Upgrade",
"analyst": "Melius",
"rating": "Hold → Buy",
"rating_from": "Hold",
"rating_to": "Buy",
"price_target": "$665",
"price_target_from": null,
"price_target_to": 665.0
}
],
"news": [
{
"published": "2026-10-24T07:00",
"title": "Do machines have feelings? AI has philosophers and tech leaders rethinking consciousness.",
"source": "MarketWatch",
"url": "https://www.marketwatch.com/story/..."
}
],
"holders": [
{ "name": "BlackRock, Inc.", "kind": "manager", "ownership_pct": 8.1763, "investor_id": "2012383" }
]
}market_cap,enterprise_value,sales,net_income,assets_under_management,net_flows_*: US dollars, whole numbers.shares_outstanding,shares_float,short_interest,volume,avg_volume: shares, whole numbers.- Fields ending in
_pctare percentages:2.5means 2.5%.sma50_distance_pctis the price's distance from its 50-day average,from_52w_high_pctits distance from the 52-week high. analyst_recommendationruns from 1 (strong buy) to 5 (strong sell).short_ratiois days to cover.- Dates are ISO (
2026-10-28); news and filing times are New York time (2026-10-24T07:00). - A field is
nullwhen Finviz shows no value (a P/E for a company with losses, a forecast not yet published).
examples/dividend_screen.py: screen large, profitable dividend payers and save the columns dividend investors look at to CSV.examples/insider_buying_report.py: take the biggest recent insider purchases and add each stock's valuation, analyst target and performance in one JSON report.examples/week_ahead.py: print the week's major economic releases and the earnings of companies over $50B, day by day.
- Finviz shows 20 screener rows per page to visitors without an Elite account, so large screens take one request per 20 rows. Elite-only filters and options are marked in
filtersand reported as ignored if you use them. - Finviz covers stocks and ETFs listed on US exchanges, including ADRs of foreign companies.
- Data on finviz.com belongs to Finviz and its data providers. Respect its terms of use, keep request volumes reasonable and cache what you have already fetched. This project is not affiliated with Finviz.
src/finviz_scraper/
__init__.py package exports and version
scraper.py FinvizScraper: fetching, retries, screener paging, ignored-filter checks
parsing.py screener JSON, quote/insider/group HTML (BeautifulSoup) and calendar parsers
fields.py Finviz keys and labels mapped to snake_case field names
models.py dataclasses for quotes, trades, ratings, news and calendar events
urls.py URL builders and the filter, signal, view and sort vocabularies
values.py number, percentage and date parsing
export.py JSON / JSONL / CSV / table output
cli.py the finviz-scraper command
examples/ runnable scripts (CSV screen, JSON report, weekly calendar)
tests/ offline tests with real, trimmed Finviz pages (no API calls)
python -m pip install -e ".[dev]"
make lint # ruff check + format check
make test # pytest, fully offline: the API client is mockedpre-commit install runs ruff on every commit (see .pre-commit-config.yaml).
- ScrapeUnblocker: web scraping API that gets past blocks and CAPTCHAs
- ScrapeUnblocker documentation
- Python SDK
MIT © 2026 ScrapeUnblocker