# Morningstar Scraper (`maximedupre/morningstar-scraper`) Actor

Scrape public Morningstar data for stocks, mutual funds, and ETFs. Get prices, ratings, fees, assets, holdings, sector exposure, source IDs, and audit facts from URLs, symbols, or search phrases.

- **URL**: https://apify.com/maximedupre/morningstar-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$9.00 / 1,000 scraped investments

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

### 📈 Morningstar scraper for stock and fund data

Morningstar Scraper extracts public investment data from [Morningstar](https://www.morningstar.com/) for stocks, mutual funds, and ETFs. Paste Morningstar URLs, symbols such as `AAPL`, fund symbols such as `VFIAX`, ETF symbols such as `VOO`, or search phrases such as `Vanguard index fund`, and the Actor saves source-backed rows to an Apify dataset.

Use this Morningstar scraper when you need repeatable investment research data for portfolio review, fund screening, market dashboards, lead lists, finance apps, or spreadsheet workflows. Instead of opening Morningstar quote pages by hand, you can run the Actor in Apify Console, call it through the Apify API, schedule recurring runs, export CSV/JSON/Excel files, or connect finished datasets to webhooks and integrations.

For a first run, keep the prefilled targets. They show the mixed target flow with a stock symbol, fund symbol, ETF symbol, Morningstar URL, and search phrase before you add your own larger list.

### ✅ What this Actor does

- Scrapes public Morningstar stock quote and profile pages.
- Scrapes public Morningstar mutual fund research pages.
- Scrapes public Morningstar ETF research pages.
- Accepts Morningstar URLs, stock tickers, mutual fund symbols, ETF symbols, and search phrases.
- Resolves exact URLs and symbols before using search phrase discovery.
- Saves one dataset row per successful public Morningstar investment result.
- Returns source-backed quote, valuation, classification, fee, asset, holding, and sector exposure facts when Morningstar shows them.
- Runs without your Morningstar login, cookies, API key, paid Morningstar Direct access, or third-party financial data provider.

The Actor is focused on public Morningstar data. It does not scrape logged-in Morningstar dashboards, private portfolios, paid Morningstar Direct data, alerts, recommendations, analyst summaries, or investment advice.

### 📦 Data you can extract

Each output item represents one successful Morningstar stock, mutual fund, or ETF result. Fields can include:

- `target` for the submitted URL, symbol, or phrase that produced the row.
- `instrumentType` as `stock`, `fund`, or `etf`.
- `symbol`, `exchange`, `name`, and `sourceId` for source identity and reruns.
- `currency`, `price`, `priceChange`, and `priceChangePercent`.
- `marketCap`, `peRatio`, `dividendYieldPercent`, `beta`, and `fiftyTwoWeekRange` when visible.
- Morningstar facts such as `fairValue`, `starRating`, and `economicMoat` when public pages show them.
- `sector` and `industry` for stocks when available.
- `category`, `expenseRatioPercent`, `netAssets`, `fundFamily`, and `investmentStyle` for funds and ETFs when available.
- `returns`, `holdings`, and `sectorExposure` when Morningstar exposes those facts publicly.
- `sourceFacts` with useful source-visible label/value pairs for audit.

Some fields can be `null` because Morningstar does not show every fact for every investment type. The Actor leaves missing public facts empty instead of filling them from another source or guessing.

### 🎯 Common use cases

- Collect Morningstar stock quote data for a watchlist.
- Compare mutual fund categories, expense ratios, assets, ratings, and holdings.
- Pull ETF research rows into a spreadsheet or dashboard.
- Build a repeatable input list from Morningstar URLs copied during manual research.
- Use search phrases to discover several matching Morningstar investments.
- Schedule recurring exports for the same ticker, fund, or ETF list.
- Keep source IDs and raw source facts for audit-friendly downstream checks.

### 🚀 How to run it

1. Open the Input tab.
2. Add targets in **Morningstar targets**. Use one target per line.
3. Optional: set **Asset scope** when search phrases should return only stocks, mutual funds, or ETFs.
4. Set **Search results per target** for broad search phrases.
5. Start the Actor and open the dataset.

You can export the dataset as JSON, CSV, Excel, XML, RSS, or HTML. You can also pull the same rows through the Apify API after the run finishes.

### ⚙️ Input example

```json
{
	"targets": [
		"AAPL",
		"VFIAX",
		"VOO",
		"https://www.morningstar.com/stocks/xnas/aapl/quote",
		"Vanguard 500"
	],
	"assetScope": "all",
	"maxSearchResultsPerTarget": 5
}
````

`targets` is the list of Morningstar URLs, symbols, tickers, or search phrases to collect.

`assetScope` controls result types for search phrases. Exact Morningstar URLs and symbols still resolve to their matching source type.

`maxSearchResultsPerTarget` caps how many Morningstar search matches are saved for each search phrase. Exact URLs and exact symbols return their direct match.

### 🧾 Output example

```json
{
	"target": "AAPL",
	"instrumentType": "stock",
	"symbol": "AAPL",
	"exchange": "XNAS",
	"name": "Apple Inc",
	"sourceId": "stocks/xnas/aapl/quote",
	"currency": "USD",
	"price": 297.89,
	"priceChange": 1.94,
	"priceChangePercent": 0.66,
	"marketCap": 4380000000000,
	"peRatio": 36.04,
	"dividendYieldPercent": 0.35,
	"beta": null,
	"fiftyTwoWeekRange": {
		"low": 196.86,
		"high": 317.4
	},
	"fairValue": 289,
	"starRating": 3,
	"economicMoat": null,
	"sector": "Technology",
	"industry": "Consumer Electronics",
	"category": null,
	"expenseRatioPercent": null,
	"netAssets": null,
	"fundFamily": null,
	"investmentStyle": "Large Core",
	"returns": {
		"ytdPercent": null,
		"oneYearPercent": null,
		"threeYearPercent": null,
		"fiveYearPercent": null
	},
	"holdings": [],
	"sectorExposure": [],
	"sourceFacts": [
		{
			"label": "Market Cap",
			"value": "$4.38T"
		}
	]
}
```

### 💳 Pricing

This Actor uses pay-per-event pricing. It charges one `investment-result` event only after a successful public Morningstar stock, mutual fund, or ETF result is saved.

The planned price is `$0.009` per successful result, or `$9.00 per 1,000 results`. Failed, invalid, unresolved, blocked, unsupported, or skipped targets do not create dataset rows and are not charged as results.

### ⚠️ Limits and notes

- Morningstar can show different fields for stocks, mutual funds, and ETFs.
- Public pages can hide or omit some Morningstar facts. Missing source facts are returned as `null` or empty arrays.
- Search phrases can match more than one Morningstar investment. Use **Search results per target** to keep broad phrases predictable.
- This Actor does not provide investment advice, recommendations, price alerts, or analyst summaries.
- The `sourceId` field is the canonical Morningstar path. A full URL can be reconstructed from it, so the dataset does not repeat a separate source URL field.

### ❓ FAQ

#### Can I use Morningstar URLs directly?

Yes. Paste Morningstar stock, mutual fund, or ETF quote URLs in **Morningstar targets**. The Actor stores the canonical Morningstar path in `sourceId`.

#### Do I need a Morningstar account?

No. The Actor is built for public Morningstar pages and does not ask for Morningstar cookies, login credentials, API keys, or Morningstar Direct access.

#### Why are some fields empty?

Morningstar does not show every fact for every investment type or page. The Actor keeps unavailable public facts empty instead of guessing or mixing in data from another provider.

#### Can I use this through the Apify API?

Yes. Run the Actor from Apify Console or call it with the Apify API, then export or read the default dataset from your own workflow.

### 📝 Changelog

- 0.1: Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~morningstar-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Other actors

- [Bitget Tickers Scraper ↗](https://apify.com/maximedupre/bitget-tickers-scraper) - Export live crypto market ticker snapshots for prices, volume, spreads, and futures data.
- [Arkham Intelligence Wallet Data Scraper ↗](https://apify.com/maximedupre/arkham-intelligence-wallet-data-scraper) - Collect public wallet analytics, balances, portfolio snapshots, and entity labels.
- [GMGN Wallet Activity Scraper ↗](https://apify.com/maximedupre/gmgn-wallet-activity-scraper) - Export public wallet trades, transfers, liquidity events, token data, and transaction links.
- [Ahrefs Free Website Stats Scraper ↗](https://apify.com/maximedupre/ahrefs-free-website-stats-scraper) - Collect public Ahrefs website metrics for domains and competitor research.
- [SEMrush Free Website Stats Scraper ↗](https://apify.com/maximedupre/semrush-free-website-stats-scraper) - Export public SEMrush overview metrics such as traffic, authority, backlinks, and referring domains.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `targets` (type: `array`):

Enter one target per line. Use Morningstar URLs, stock tickers, mutual fund symbols, ETF symbols, or search phrases such as Vanguard index fund.

## `assetScope` (type: `string`):

Choose which Morningstar result type to collect for search phrases. Exact URLs and symbols still resolve to their matching type.

## `maxSearchResultsPerTarget` (type: `integer`):

Maximum Morningstar matches to collect for each search phrase. Exact URLs and symbols return their direct match.

## Actor input object example

```json
{
  "targets": [
    "AAPL",
    "VFIAX",
    "VOO",
    "https://www.morningstar.com/stocks/xnas/aapl/quote",
    "Vanguard 500"
  ],
  "assetScope": "all",
  "maxSearchResultsPerTarget": 5
}
```

# Actor output Schema

## `results` (type: `string`):

Successful Morningstar rows with source-backed prices, ratings, fees, assets, holdings, sector exposure, and audit facts.

# 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 = {
    "targets": [
        "AAPL",
        "VFIAX",
        "VOO",
        "https://www.morningstar.com/stocks/xnas/aapl/quote",
        "Vanguard 500"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/morningstar-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 = { "targets": [
        "AAPL",
        "VFIAX",
        "VOO",
        "https://www.morningstar.com/stocks/xnas/aapl/quote",
        "Vanguard 500",
    ] }

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

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

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

```

## CLI example

```bash
echo '{
  "targets": [
    "AAPL",
    "VFIAX",
    "VOO",
    "https://www.morningstar.com/stocks/xnas/aapl/quote",
    "Vanguard 500"
  ]
}' |
apify call maximedupre/morningstar-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=maximedupre/morningstar-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Morningstar Scraper",
        "description": "Scrape public Morningstar data for stocks, mutual funds, and ETFs. Get prices, ratings, fees, assets, holdings, sector exposure, source IDs, and audit facts from URLs, symbols, or search phrases.",
        "version": "0.1",
        "x-build-id": "MBpa2ImVlD9uuPIdP"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/maximedupre~morningstar-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-maximedupre-morningstar-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/maximedupre~morningstar-scraper/runs": {
            "post": {
                "operationId": "runs-sync-maximedupre-morningstar-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/maximedupre~morningstar-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-maximedupre-morningstar-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "targets"
                ],
                "properties": {
                    "targets": {
                        "title": "Morningstar targets",
                        "minItems": 1,
                        "maxItems": 500,
                        "type": "array",
                        "description": "Enter one target per line. Use Morningstar URLs, stock tickers, mutual fund symbols, ETF symbols, or search phrases such as Vanguard index fund.",
                        "items": {
                            "type": "string",
                            "minLength": 1
                        }
                    },
                    "assetScope": {
                        "title": "Asset scope",
                        "enum": [
                            "all",
                            "stocks",
                            "funds",
                            "etfs"
                        ],
                        "type": "string",
                        "description": "Choose which Morningstar result type to collect for search phrases. Exact URLs and symbols still resolve to their matching type.",
                        "default": "all"
                    },
                    "maxSearchResultsPerTarget": {
                        "title": "Search results per target",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum Morningstar matches to collect for each search phrase. Exact URLs and symbols return their direct match.",
                        "default": 5
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
