Krak.dk Business Directory Scraper
Pricing
from $3.00 / 1,000 results
Krak.dk Business Directory Scraper
Scrape Krak.dk, Denmark's leading business and phone directory. Search by keyword, browse by category and kommune (municipality), or fetch business detail pages directly. Get name, address, phone, email, website, CVR number, opening hours area, rating, and more - no login required.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Crawler Bros
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Scrape Krak.dk, Denmark's leading business and phone directory. Search any keyword, browse by category and kommune (municipality), or fetch specific business detail pages — no login, no cookies, no API key required.
What this actor does
- Three modes:
search(free-text, e.g. "restaurant København"),byCategory(browse a curated category + one of Denmark's 98 kommuner, or nationwide),byUrl(fetch specific business detail pages) - Rich business data: name, categories, full address (street/postal code/city), GPS coordinates, phone, email, website, CVR number (Danish company registration ID), founding date, employee count, rating and review count
- Nationwide coverage for category browsing:
byCategorywithout a specific kommune automatically shards the browse across all 98 Danish municipalities to reach highermaxItemsvalues, working around Krak.dk's ~25-results-per-query page cap (see Limitations) - Filters: location text filter (city/postal code/kommune), minimum rating, free-text keyword filter
- Empty fields are omitted — every record only contains data actually found for that business
- Full Danish UTF-8 support — city names, addresses, and descriptions preserve Danish characters exactly (København, Æbeltoft, Ålborg-style spellings, etc.)
Output per business
businessId,sourceUrl— unique numeric ID and canonical Krak.dk detail-page URLnamecategories[]— trade/branche tags (e.g.Restaurant,Café) (richer whenfetchDetails: true)businessType— schema.org business type from the listing card (e.g.Restaurant,BarOrPub) (listing-only, omitted oncecategoriesis available from the detail page)street,postalCode,city,fullAddresslatitude,longitude(detail only)phone,email(detail only),website(detail only — the business's own external site, not a krak.dk link)socialLinks[]— social media / external profile URLs (e.g. Facebook, Instagram) published on the business's profile (detail only, when published)mapUrl— Krak.dk's map link for the business (detail only)cvrNumber— Danish company registration number (CVR) (detail only)foundingDate— ISOYYYY-MM-DD(detail only, when published)numberOfEmployees(detail only, when published)rating(0-5),reviewCount(detail only, when the business has reviews)description(detail only, when published)recordType: "business",scrapedAt
(detail only) fields are populated when fetchDetails: true (opt-in for search/byCategory — off by default, see Limitations) or always for mode: byUrl.
Input
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | search | search / byCategory / byUrl |
searchQuery | string | restaurant København | Free-text query combining a category/trade and a place, exactly like Krak's own search bar (mode=search) |
category | string (enum) | Restaurant | One of ~62 curated categories (mode=byCategory) |
customCategory | string | – | Free-text category override, used instead of category (mode=byCategory) |
kommune | string (enum) | – | One of Denmark's 98 kommuner (mode=byCategory); leave empty for a nationwide, auto-sharded browse |
location | string | – | Free-text place (city/kommune/postal code). Combined into the query for search/byCategory, and applied everywhere as a safety-net filter |
urls | array | – | Krak.dk detail-page URLs (mode=byUrl) |
keyword | string | – | Keep only results whose name/description/categories contain this text |
minRating | number | – | Drop businesses rated below this (0-5); only applies once fetchDetails has populated rating |
fetchDetails | boolean | false | Visit each business's detail page for email/website/CVR/founding date/employee count/geo/rating/description (1 extra Playwright page load per business, several seconds each; best-effort — see Limitations) |
maxItems | integer | 25 | Hard cap (1-300) |
proxyConfiguration | object | – | Optional; Krak.dk works without a proxy, the actor auto-escalates to the free AUTO group on a persistent 403/429 |
Example: search by keyword + place
{"mode": "search","searchQuery": "VVS Vanløse","maxItems": 25}
Example: browse a category within one kommune
{"mode": "byCategory","category": "Frisør","kommune": "Odense","fetchDetails": true,"maxItems": 50}
Example: browse a category nationwide (auto-sharded across kommuner)
{"mode": "byCategory","category": "Tandlæge","maxItems": 200}
Example: fetch specific business pages
{"mode": "byUrl","urls": ["https://www.krak.dk/caf%C3%A9+zirup+k%C3%B8benhavn+k/67493772/firma"]}
Limitations
- Krak.dk requires a real browser (Cloudflare Turnstile). Krak.dk fronts every page with Cloudflare's JS challenge (
cf-mitigated: challenge, "Just a moment..."). A plain HTTP client (even one impersonating a full Chrome TLS fingerprint) can never pass this — it requires executing real JavaScript — so this actor drives a headless, stealth-configured Chromium browser (Playwright) for every request. No proxy is used by default (a residential/datacenter proxy round-trip was tested and made no difference to whether the challenge passed, and Apify's free AUTO datacenter proxy group timed out entirely against krak.dk in testing). - Detail-page enrichment (
fetchDetails: true) is best-effort and can be rate-blocked mid-run. krak.dk's anti-bot layer tolerates a limited burst of detail-page requests per run/IP and then escalates to a hard (non-challenge) 403 for further detail-page requests for a cooldown period; it does not rate-block the listing/search pages themselves. The actor detects this automatically (a circuit breaker disables further detail fetches after 5 consecutive failures) and falls back to listing-only data for the rest of the run rather than failing or hanging — so a run always completes and always returns real data, but the richer detail-only fields (email,website,cvrNumber,foundingDate,numberOfEmployees,latitude/longitude,rating,reviewCount, fullcategories) may be present on some, all, or none of a run's records depending on current anti-bot conditions. Because of this,fetchDetailsdefaults to off — the default run only uses the always-reliable listing data (name, address, phone,businessType) — and detail enrichment is an explicit opt-in for users who want the richer fields and can tolerate partial coverage under heavy load. - ~25 results per single Krak.dk query. Krak.dk's listing pages are server-rendered with exactly one page of results (25 items) embedded in their JSON-LD
ItemList— no workingpage=/offset=/cursor parameter exists (confirmed by testing multiple variants against the live site; all return the identical first page). This is an upstream limit, not an actor bug.mode: byCategorywithout a specifickommune/locationworks around it by automatically shard-querying across all 98 kommuner (deduplicated by business ID) to reach highermaxItemsvalues;mode: searchand a location-scopedbyCategoryquery are capped at ~25 results by design. - Opening hours are not exposed. Krak.dk's own detail pages did not expose a reliable, structured per-business opening-hours field in JSON-LD or DOM during research (only Krak's own customer-service hours were found) — this field is intentionally omitted rather than shipping guessed or inconsistent data.
rating/reviewCount/categories(beyond the listing card's coarsebusinessType)/email/website/cvrNumber/foundingDate/numberOfEmployees/geo-coordinates requirefetchDetails: trueand available detail-page budget (ormode: byUrl, which always attempts the detail page) — they live only on the detail page, not the listing card.
Use cases
- Lead generation — build lists of Danish businesses by trade category and kommune
- Local SEO & marketing agencies — audit a client's phone/email/website presence on Denmark's leading directory
- Market research — measure business density and category coverage across Danish municipalities
- Data enrichment — attach CVR numbers, coordinates, and contact details to an existing company dataset
- Competitive analysis — track ratings and review counts for a category (e.g. restaurants, hairdressers) in a given city
FAQ
Do I need a proxy or login? No. Krak.dk is scraped directly with no cookies, no API key, and no Apify proxy required by default.
Why do some businesses have far more fields than others? Krak.dk only publishes what each business itself has completed on its profile (website, email, CVR, rating, etc.) — the actor never fabricates missing data; empty fields are simply omitted from that record.
Can I search for a business by name? Yes — use mode: search with the business name as searchQuery (optionally add a place, e.g. "Netto København"), or use mode: byUrl if you already have its Krak.dk profile link.