KLSE Screener — Bursa Malaysia Listed Companies
Independent tool. Trademarks referenced on this page are the property of their respective owners and are used only to identify the public website this tool reads. No affiliation or endorsement.
KLSE / Bursa Malaysia Listed Company Scraper
Scrape the entire Bursa Malaysia (KLSE) listed-company universe. Returns the full Main / ACE / LEAP market roster with current prices and fundamentals, per-company deep financials, and the live company-announcement stream mirrored from Bursa LINK.
What you get
Roster snapshot — a single call returns ~1,139 rows covering every stock listed on Bursa Malaysia's three market boards:
| Field | Description |
|---|---|
stock_code |
Bursa 4-digit code (e.g. 1155 = Maybank) |
stock_name |
Ticker short name |
company_full_name |
Full registered company name |
market_board |
MAIN / ACE / LEAP |
sector |
Bursa sector classification |
last_price |
Last traded price (MYR) |
price_change / price_change_pct |
Intraday movement |
volume |
Traded volume |
market_cap_rm |
Market capitalisation (MYR millions) |
eps |
Earnings per share (sen) |
pe_ratio |
Price/earnings ratio |
dividend_yield_pct |
Dividend yield (%) |
roe_pct |
Return on equity (%) |
nta |
Net tangible assets per share |
week_52_high / week_52_low |
52-week range |
Company deep-dive — per-company financials for specific stock codes:
- Annual revenue and net profit history
- 52-week price range, ROE, EPS, NTA, market cap, shares outstanding
- Supply a list of stock codes or leave blank to derive from the roster
Announcement stream — the live Bursa company-announcement feed, paginated:
- Announcement title, category, company name, datetime
- Categories: Financial Results, General Announcement, Changes in Corporate Info, etc.
- Filter by category or scrape all
Modes
| Mode | Input | Description |
|---|---|---|
roster_snapshot |
— | Full ~1,139-company roster with fundamentals |
company_deep |
stockCodes |
Per-company financials for supplied codes |
announcements |
announcementCategories |
Live announcement stream (paginated) |
Why KLSE Screener (not Bursa Malaysia official)
The official bursamalaysia.com site is bot-challenged on every market-data path (verified 403 + "Just a moment" interstitial). KLSE Screener mirrors the same Bursa data without that protection. The roster endpoint returns all listed companies in a single AJAX call (~2.9 MB) with complete fundamentals — no page-by-page pagination required.
Input
{
"mode": "roster_snapshot",
"maxItems": 200,
"stockCodes": ["1155", "1023"],
"sectors": [],
"announcementCategories": [],
"sp_intended_usage": "Building a screener for MY retail investors",
"sp_improvement_suggestions": ""
}
Parameters
| Parameter | Default | Description |
|---|---|---|
mode |
roster_snapshot |
Which data to scrape |
maxItems |
200 | Maximum records to return |
stockCodes |
[] |
For company_deep mode: Bursa 4-digit codes. Empty = use roster |
sectors |
[] |
For roster_snapshot: filter by sector name. Empty = all sectors |
announcementCategories |
[] |
For announcements: filter by category. Empty = all |
Resuming a large crawl
Every run emits a resumeCursor in its Output. If a large crawl stops before it finishes — because it hit maxItems, your spend cap (maxTotalChargeUsd), or was aborted — start a new run with the same input plus that resumeCursor to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.
- You are not re-charged for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its
resumeCursoris no longer valid. resumeCursoris opaque — supply it unmodified.
Output sample (roster_snapshot)
{
"record_type": "company",
"stock_code": "1155",
"stock_name": "MAYBANK",
"company_full_name": "MALAYAN BANKING BERHAD",
"market_board": "MAIN",
"sector": "Banking",
"sub_sector": "Financial Services",
"last_price": 11.1,
"price_change": 0.04,
"price_change_pct": 0.36,
"volume": 12340000,
"market_cap_rm": 134300,
"eps": 86.93,
"pe_ratio": 12.77,
"dividend_yield_pct": 5.68,
"roe_pct": 11.24,
"nta": 7.73,
"week_52_high": 12.42,
"week_52_low": 9.39,
"source_url": "https://www.klsescreener.com/v2/screener/quote_results",
"scraped_at": "2026-05-17T00:37:00.000Z"
}
Use cases
- Quant screeners: Pull the entire ~1,139-company universe with P/E, DY, ROE, EPS in one run — filter for value/dividend/growth criteria
- Retail investor tools: Power a portfolio tracker or stock discovery app for the Malaysian market
- Research desks: Monitor the Bursa announcement feed for material information, substantial-shareholding changes, and quarterly results
- Data pipelines: Feed an automated screener or alerting system — run on a schedule, compare snapshots to detect price movement or new announcements
Pricing
Per-result pricing via Apify PPE. The roster snapshot fetches all ~1,139 companies in a single network call, making it exceptionally cost-efficient for full-universe pulls.
Notes
- No API key required
- Self-throttle applies (~1 req/2s for detail pages) to respect the site's AdSense-funded free model
- Data is sourced from KLSE Screener which mirrors Bursa Malaysia's official listing; prices may lag real-time by minutes