DuckDuckGo Scraper: SERP Results as Structured JSON
A DuckDuckGo scraper that needs no API key and no account with DuckDuckGo. One query returns a page of the DuckDuckGo SERP as JSON, with ranked organic results plus the page metadata you need to paginate and audit the run.
When to use this skill
- The user wants a "DuckDuckGo scraper" or asks about "DuckDuckGo scraping" from code.
- They want DuckDuckGo search results as JSON or CSV for a query or a batch of queries.
- They need a search feed that does not require registering for an official search API key.
- They want results localized to a specific country and language, or filtered to a recent time window.
Not for: Google, Yandex, or Baidu SERPs (each engine has its own Actor, see references/actor-index.md). For rank checking and agent-side research on DuckDuckGo, use the companion DuckDuckGo MCP SERP research skill.
What you get (one dataset item per page)
Each dataset item is one page of results, not one row per link. Confirmed on a live run:
- Query echo and settings:
query, localization, safe_search, max_pages, search_timestamp
- Page counters:
total_results_found, pages_processed, page_number
search_metadata object: localization, localization_name, safe_search, safe_search_description, max_pages, pagination_limit_reached
pagination_info object: total_pages, max_pages_set, pagination_stopped_by_limit, and results_per_page with first_page and subsequent_pages
organic_results array. Every row carries position, title, link, snippet, favicon. Rows also carry date and date_raw when DuckDuckGo shows a published date (9 of 11 rows on the test query).
- Additional arrays that come back on every item and fill in when DuckDuckGo shows those blocks for the query:
ads, knowledge_graph, news_results, inline_images, inline_videos, related_searches. They were empty for the plain informational test query.
Flatten organic_results client-side if you want one CSV row per link.
Prerequisites
The Actor
Run it with the Apify CLI
One page of US English results for a query:
apify actors call "johnvc/DuckDuckGo-Scraper-for-serp-rankings" -i '{"query":"privacy focused search engine","max_pages":1}' \
--json \
--user-agent apify-awesome-skills/apify-duckduckgo-scraper \
2>/dev/null
Two pages of German results from the past week, safe search off:
apify actors call "johnvc/DuckDuckGo-Scraper-for-serp-rankings" -i '{"query":"crm software","localization":"de-de","date_filter":"w","safe":"off","max_pages":2}' \
--json \
--user-agent apify-awesome-skills/apify-duckduckgo-scraper \
2>/dev/null
Confirm live pricing and the input schema before a large batch:
apify actors info "johnvc/DuckDuckGo-Scraper-for-serp-rankings" --json \
--user-agent apify-awesome-skills/apify-duckduckgo-scraper \
2>/dev/null
Every call carries the three flags this repo expects: --json, --user-agent apify-awesome-skills/apify-duckduckgo-scraper, and 2>/dev/null.
Run it from Claude or another AI agent (MCP)
The Actor is MCP-ready. Add the hosted server URL:
https://mcp.apify.com/?tools=actors,docs,johnvc/DuckDuckGo-Scraper-for-serp-rankings
Then ask, for example: "Scrape one page of DuckDuckGo results for 'open source password manager' and list the organic links with their positions." MCP setup docs: https://docs.apify.com/platform/integrations/mcp
Workflow
- Build the query.
query is the only required field, minimum one character.
- Pick the market.
localization takes a region and language code such as us-en, uk-en, de-de, fr-fr, ja-jp. Default is us-en. There are 42 codes in the schema.
- Narrow if needed.
date_filter accepts d, w, m, y, or an explicit range like 2026-01-01..2026-05-01. safe accepts strict, moderate (default), or off.
- Bound the volume.
max_pages defaults to 2 and is the cost driver. 0 means no limit, which is worth avoiding unless the user has agreed to an open-ended spend.
- Estimate cost, then run. See
references/gotchas.md for the arithmetic and confirmation thresholds.
- Read the dataset. Each item is one page. Concatenate
organic_results across items, keeping page_number if you need to preserve global ordering.
Inputs
query (string, required): the search term
localization (enum, 42 region and language codes, default us-en)
safe (enum strict, moderate, off, default moderate)
date_filter (string): d, w, m, y, or YYYY-MM-DD..YYYY-MM-DD
max_pages (integer 0 to 100, default 2): 0 means no limit
output_file (string): also write results to this filename in the run key-value store
Cost
Billing is pay per event: a fractions-of-a-cent setup fee per run plus a per-page fee, so cost tracks max_pages almost exactly. A default two-page run lands around two cents. Live prices and batch thresholds are in references/gotchas.md.
Honest limits
- Results reflect the SERP at crawl time for the chosen
localization. Repeat runs can differ as DuckDuckGo reindexes.
- The first page returned fewer rows than later pages on the test run (
results_per_page reported 11 for the first page and 50 for subsequent pages), so do not assume a fixed page size when computing global positions.
ads, knowledge_graph, news_results, inline_images, inline_videos, and related_searches are present on every item but only fill in when DuckDuckGo renders those blocks. Plain informational queries often return all six empty.
date and date_raw are per-row and optional. Treat a missing date as unknown, not as recent.
Troubleshooting
- Empty
organic_results: the query returned nothing for that region. Broaden the query or try localization us-en.
- Fewer pages than
max_pages: DuckDuckGo ran out of results. Check pagination_limit_reached and pagination_stopped_by_limit.
- Rejected
date_filter: the field is pattern-validated. Use a single letter or the exact YYYY-MM-DD..YYYY-MM-DD form.
- Unexpected spend:
max_pages 0 removes the cap. Set an explicit integer for anything unattended.
See references/gotchas.md for cost guardrails and error recovery, and references/actor-index.md for the Actor routing table.
Related search Actors
1---2name: apify-duckduckgo-scraper3description: Scrape DuckDuckGo search results into structured JSON with the Apify DuckDuckGo Scraper Actor (johnvc/DuckDuckGo-Scraper-for-serp-rankings). One query returns a page item holding organic_results rows with position, title, link, snippet, favicon, and a date when DuckDuckGo shows one, plus page metadata and slots for ads, knowledge graph, news, inline images, inline videos, and related searches. Localize across 42 region and language codes, filter by date, set safe search, and cap pages to control spend. Use when the user wants a duckduckgo scraper, duckduckgo scraping, DuckDuckGo search results as JSON or CSV, a DuckDuckGo SERP export, or a keyless way to read DuckDuckGo from code. Pay-per-page billing, MCP-ready for Claude and other AI agents.4license: MIT5---67# DuckDuckGo Scraper: SERP Results as Structured JSON89A DuckDuckGo scraper that needs no API key and no account with DuckDuckGo. One query returns a page of the DuckDuckGo SERP as JSON, with ranked organic results plus the page metadata you need to paginate and audit the run.1011## When to use this skill1213- The user wants a "DuckDuckGo scraper" or asks about "DuckDuckGo scraping" from code.14- They want DuckDuckGo search results as JSON or CSV for a query or a batch of queries.15- They need a search feed that does not require registering for an official search API key.16- They want results localized to a specific country and language, or filtered to a recent time window.1718Not for: Google, Yandex, or Baidu SERPs (each engine has its own Actor, see `references/actor-index.md`). For rank checking and agent-side research on DuckDuckGo, use the companion DuckDuckGo MCP SERP research skill.1920## What you get (one dataset item per page)2122Each dataset item is one page of results, not one row per link. Confirmed on a live run:2324- Query echo and settings: `query`, `localization`, `safe_search`, `max_pages`, `search_timestamp`25- Page counters: `total_results_found`, `pages_processed`, `page_number`26- `search_metadata` object: `localization`, `localization_name`, `safe_search`, `safe_search_description`, `max_pages`, `pagination_limit_reached`27- `pagination_info` object: `total_pages`, `max_pages_set`, `pagination_stopped_by_limit`, and `results_per_page` with `first_page` and `subsequent_pages`28- `organic_results` array. Every row carries `position`, `title`, `link`, `snippet`, `favicon`. Rows also carry `date` and `date_raw` when DuckDuckGo shows a published date (9 of 11 rows on the test query).29- Additional arrays that come back on every item and fill in when DuckDuckGo shows those blocks for the query: `ads`, `knowledge_graph`, `news_results`, `inline_images`, `inline_videos`, `related_searches`. They were empty for the plain informational test query.3031Flatten `organic_results` client-side if you want one CSV row per link.3233## Prerequisites3435- Apify account (sign up at https://apify.com?fpr=9n7kx3&fp_sid=skillrepo).36- Authentication via `apify login`, or an `APIFY_TOKEN` environment variable (Apify Console, Settings, Integrations).3738## The Actor3940- Store page: https://apify.com/johnvc/DuckDuckGo-Scraper-for-serp-rankings?fpr=9n7kx3&fp_sid=skillrepo41- Actor ID: `johnvc/DuckDuckGo-Scraper-for-serp-rankings`42- Pricing: a tiny per-run setup fee plus a per-page fee (see `references/gotchas.md`).4344## Run it with the Apify CLI4546One page of US English results for a query:4748```bash49apify actors call "johnvc/DuckDuckGo-Scraper-for-serp-rankings" -i '{"query":"privacy focused search engine","max_pages":1}' \50 --json \51 --user-agent apify-awesome-skills/apify-duckduckgo-scraper \52 2>/dev/null53```5455Two pages of German results from the past week, safe search off:5657```bash58apify actors call "johnvc/DuckDuckGo-Scraper-for-serp-rankings" -i '{"query":"crm software","localization":"de-de","date_filter":"w","safe":"off","max_pages":2}' \59 --json \60 --user-agent apify-awesome-skills/apify-duckduckgo-scraper \61 2>/dev/null62```6364Confirm live pricing and the input schema before a large batch:6566```bash67apify actors info "johnvc/DuckDuckGo-Scraper-for-serp-rankings" --json \68 --user-agent apify-awesome-skills/apify-duckduckgo-scraper \69 2>/dev/null70```7172Every call carries the three flags this repo expects: `--json`, `--user-agent apify-awesome-skills/apify-duckduckgo-scraper`, and `2>/dev/null`.7374## Run it from Claude or another AI agent (MCP)7576The Actor is MCP-ready. Add the hosted server URL:7778`https://mcp.apify.com/?tools=actors,docs,johnvc/DuckDuckGo-Scraper-for-serp-rankings`7980Then ask, for example: "Scrape one page of DuckDuckGo results for 'open source password manager' and list the organic links with their positions." MCP setup docs: https://docs.apify.com/platform/integrations/mcp8182## Workflow83841. Build the query. `query` is the only required field, minimum one character.852. Pick the market. `localization` takes a region and language code such as `us-en`, `uk-en`, `de-de`, `fr-fr`, `ja-jp`. Default is `us-en`. There are 42 codes in the schema.863. Narrow if needed. `date_filter` accepts `d`, `w`, `m`, `y`, or an explicit range like `2026-01-01..2026-05-01`. `safe` accepts `strict`, `moderate` (default), or `off`.874. Bound the volume. `max_pages` defaults to 2 and is the cost driver. `0` means no limit, which is worth avoiding unless the user has agreed to an open-ended spend.885. Estimate cost, then run. See `references/gotchas.md` for the arithmetic and confirmation thresholds.896. Read the dataset. Each item is one page. Concatenate `organic_results` across items, keeping `page_number` if you need to preserve global ordering.9091## Inputs9293- `query` (string, required): the search term94- `localization` (enum, 42 region and language codes, default `us-en`)95- `safe` (enum `strict`, `moderate`, `off`, default `moderate`)96- `date_filter` (string): `d`, `w`, `m`, `y`, or `YYYY-MM-DD..YYYY-MM-DD`97- `max_pages` (integer 0 to 100, default 2): `0` means no limit98- `output_file` (string): also write results to this filename in the run key-value store99100## Cost101102Billing is pay per event: a fractions-of-a-cent setup fee per run plus a per-page fee, so cost tracks `max_pages` almost exactly. A default two-page run lands around two cents. Live prices and batch thresholds are in `references/gotchas.md`.103104## Honest limits105106- Results reflect the SERP at crawl time for the chosen `localization`. Repeat runs can differ as DuckDuckGo reindexes.107- The first page returned fewer rows than later pages on the test run (`results_per_page` reported 11 for the first page and 50 for subsequent pages), so do not assume a fixed page size when computing global positions.108- `ads`, `knowledge_graph`, `news_results`, `inline_images`, `inline_videos`, and `related_searches` are present on every item but only fill in when DuckDuckGo renders those blocks. Plain informational queries often return all six empty.109- `date` and `date_raw` are per-row and optional. Treat a missing date as unknown, not as recent.110111## Troubleshooting112113- Empty `organic_results`: the query returned nothing for that region. Broaden the query or try `localization` `us-en`.114- Fewer pages than `max_pages`: DuckDuckGo ran out of results. Check `pagination_limit_reached` and `pagination_stopped_by_limit`.115- Rejected `date_filter`: the field is pattern-validated. Use a single letter or the exact `YYYY-MM-DD..YYYY-MM-DD` form.116- Unexpected spend: `max_pages` `0` removes the cap. Set an explicit integer for anything unattended.117118See `references/gotchas.md` for cost guardrails and error recovery, and `references/actor-index.md` for the Actor routing table.119120## Related search Actors121122- DuckDuckGo MCP SERP research (rank checking, the companion skill for this Actor)123- Yandex Search Scraper: https://apify.com/johnvc/Scrape-Yandex?fpr=9n7kx3&fp_sid=skillrepo124- Baidu Search Scraper: https://apify.com/johnvc/Baidu-Search-Scraper?fpr=9n7kx3&fp_sid=skillrepo125- Naver Search API (Korea): https://apify.com/johnvc/naver-search-api?fpr=9n7kx3&fp_sid=skillrepo