DuckDuckGo Scraper By Keyword List & Rank Position
Pricing
from $3.99 / 1,000 results
DuckDuckGo Scraper By Keyword List & Rank Position
DuckDuckGo Scraper By Keyword List & Rank Position extracts DuckDuckGo search results for keyword lists, including titles, URLs, snippets, domains, rank positions, and search metadata. Ideal for SEO tracking, keyword research, competitor analysis, and SERP monitoring.
Pricing
from $3.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Share
DuckDuckGo Scraper โ Extract Search Results, News and Videos
DuckDuckGo scraper built around one question SEOs and brand owners actually ask: where do we show up, and who is above us? Give it a keyword โ or a whole list โ and it returns every search result as typed JSON, each row carrying the exact rank position DuckDuckGo returned it at, the page it came from, and a flag for whether it landed on a domain you're watching. Unlike scraping frameworks that hand back raw HTML, this Actor returns clean, normalized fields ready for a spreadsheet, a database, or an LLM context window โ no parsing required. Covers web, news and video search, all without a DuckDuckGo account or API key. This guide covers every input and output field, how the ranking logic actually works, and three ways teams run it in production.
๐งญ What Does DuckDuckGo Scraper By Keyword List & Rank Position Do?
This Actor queries DuckDuckGo the way a browser does โ no login, no API key, no DuckDuckGo developer account โ and returns organic web results, news headlines, or video listings as structured rows. It runs an entire list of keywords in one job instead of one query per invocation, numbers every result with the rank position DuckDuckGo actually returned it at, and flags any row whose host matches a domain you're tracking. Positions are counted from the real returned order, after duplicate URLs across pages are removed, and are never re-numbered after filtering.
- Runs a single keyword or a full
keywordList, one job per run - Accepts a plain query or a full
duckduckgo.com/?q=...URL, with the URL's own region overriding the run default for that keyword - Numbers every result with
position,pageNumberandpositionOnPage - Flags rows against a
watchDomainslist, with subdomain matching optional - Supports web, news and video search modes with the same ranking logic in all three
- Escalates automatically through direct, datacenter and residential proxies when DuckDuckGo blocks an exit IP
- Writes a per-keyword
RANK_SUMMARYโ best position and every matching URL per watched domain โ to the run's key-value store
โก Features & Capabilities
Three groups of capability sit behind this Actor: what it extracts, how it holds up against other DuckDuckGo scrapers, and where it fits in the wider Scrapio lineup.
Core features
- Keyword list, not single query.
keywordListtakes as many terms as you like, one per line; each gets its own DuckDuckGo session and its own independent position numbering, recorded in thekeywordfield on every row. - Real rank position.
positionis 1-indexed, continued across pages, and counted after cross-page URL de-duplication โ DuckDuckGo's own pages repeat a result or two between page 1 and page 2, and numbering the raw pages back-to-back would shift every later position. - Watched-domain flags.
isWatchedDomainandmatchedWatchDomainare added to every row whenwatchDomainsis set; bare domains,www.prefixes and full URLs all normalize to the same host, and subdomain matching is a toggle (matchSubdomains). - Watched-only mode.
onlyWatchedDomainssaves only your rows while keeping their true SERP position, so a saved row can legitimately readposition: 7with nothing else above it in the dataset. - Three search modes.
searchModeswitches between web (default),newsandvideos; the ranking and watch logic behaves identically in all three, only the field set changes. - Automatic anti-bot handling. A deterministic solver answers DuckDuckGo's inline
jsaJavaScript challenge, and a proxy ladder rotates from direct exit โ Apify datacenter โ Apify residential on a real anomaly block. - 63 search regions. From
wt-wt(all regions) to locale-specific options likede-deorjp-jp, sent to DuckDuckGo as thelparameter.
How DuckDuckGo Scraper By Keyword List & Rank Position compares to other DuckDuckGo scrapers
| Feature | This Actor | epctex/duckduckgo-scraper | jaybird/duckduckgo-scraper (DuckDuckGo SERP Scraper) |
|---|---|---|---|
| Multiple keywords in one run | Yes โ keywordList, unlimited terms | No โ single search parameter per run | Yes โ accepts multiple search terms |
| Rank/position field on rows | Yes โ position, pageNumber, positionOnPage | Not documented on the listing | Yes โ 1-based rank, continuous across pages |
| Watched-domain flagging | Yes โ isWatchedDomain, matchedWatchDomain, plus a per-keyword best-position rollup in RANK_SUMMARY | Not documented on the listing | Not documented on the listing |
| Search modes | Web, news, videos | Web, images, videos, news | Web, news, images, videos, suggestions, instant answers |
| Anti-bot handling | Documented JS-challenge solver + direct โ datacenter โ residential proxy escalation | Not documented on the listing | Not documented on the listing |
| Pricing model | Apify pay-per-result | Monthly rental (developer fee) + platform usage | Apify pay-per-event |
(Competitor rows above reflect each Actor's own Apify Store listing as observed on 2026-08-16; features they don't publish are marked "not documented" rather than assumed absent.)
If your use case is feeding structured data to an LLM, the watched-domain and rank-position rows are the decision-maker here โ a rank-tracking workflow built on a scraper without a real position field means re-deriving rank order yourself from result order, which breaks the moment pagination or de-duplication changes it.
When another tool might suit you better
If you only need one search term checked occasionally and don't care about tracking specific domains, a lighter single-query Actor like s-r/duckduckgo-serp โ which returns rank and decoded URLs for one query per run, with no keyword-list or watch-domain layer โ is a simpler fit and likely cheaper per check. This Actor earns its keep specifically when you're running a keyword list against a watch list repeatedly, which is a narrower job than "check one query."
DuckDuckGo Scraper By Keyword List & Rank Position within the Scrapio data stack
This Actor covers DuckDuckGo web, news and video search results. For the same rank-checking job on Google, use Google-Search-Results-Serp-Scraper; for general Google SERP extraction, Google-Search-Results-Scraper; for Baidu, Baidu-Search-Scraper. It is currently the only DuckDuckGo Actor published under the Scrapio account.
Why do developers and data teams scrape DuckDuckGo?
๐ข SEO teams and marketers
An SEO team feeds a client's target keyword list into keywordList, sets watchDomains to the client's site and its main competitors, and gets back which pages hold which position for every term, per region. matchedWatchDomain turns "did we rank" into a column instead of a manual SERP read, and because DuckDuckGo doesn't personalize results the way Google does for a logged-in searcher, the numbers are closer to what any anonymous visitor actually sees.
๐ AI training data and RAG indexing
title, description (web), excerpt (news), and description (video) are the high-information text fields โ each cleaned of HTML tags and entities, with a rawDescription/rawExcerpt twin kept for anyone who wants the original markup. For RAG, these text fields plus url and hostname make a directly indexable passage-and-source pair. For training data, every field returns as a typed primitive (string, integer, boolean, or explicit null) with a stable key set per mode, so no schema drift needs handling downstream.
๐ฑ Competitive and market intelligence
Track a competitor's hostname across your keyword list run over run, or set them as a watchDomains entry and read matchedWatchDomain straight off the dataset. The RANK_SUMMARY key-value record adds a bestPosition per domain per keyword โ the single number a market-intelligence dashboard actually needs, without recomputing it from raw rows.
๐ฌ Research and academic use
DuckDuckGo doesn't personalize search the way Google does, which makes it a useful comparison point for research into search-result diversity, ranking stability, or algorithm behavior across regions using the region parameter. This Actor returns only publicly accessible search result data, suitable for public-data research datasets.
๐ฅ Product and SaaS development
The RANK_SUMMARY and position fields are a ready-made backend for a rank-tracking dashboard, an enrichment API, or a monitoring tool โ schedule the Actor, store the dataset, and diff bestPosition values run over run to build a movement feed without writing a ranking engine from scratch.
๐ Input Parameters
Read directly from the Actor's input schema. Required fields: searchMode, region, safeSearch.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
searchKeyword | No | string | The first search term to rank-check. Search operators work โ site:example.com, filetype:pdf, inurl:, intitle: and "exact phrase" are all verified working. Leave empty to put everything in keywordList instead. | "project management software" |
keywordList | No | array (default []) | Extra search terms run in the same job, one per line. Each is searched with the same mode, region and safe-search settings; every row records which keyword produced it in the keyword column. A full DuckDuckGo search URL is also accepted โ the query is lifted out of it and the URL's own kl locale overrides the region for that keyword only. Duplicates are removed. Each keyword needs its own DuckDuckGo session, so a long list costs proportionally more and residential proxies are recommended past a handful of terms. | ["best crm for agencies"] |
searchMode | Yes | string, default "default", enum default | news | videos | Classic web links, news headlines, or videos. Positions are numbered the same way in all three. | "default" |
region | Yes | string, default "wt-wt", 63-value enum | The locale DuckDuckGo searches from, sent as the l parameter. A position measured here is a position for THIS region only. | "us-en" |
safeSearch | Yes | string, default "OFF", enum OFF | MODERATE | STRICT | Sent to DuckDuckGo as the p filter parameter. STRICT is measurably enforced โ an adult keyword returns 0 rows under STRICT and 10 rows under OFF. MODERATE and OFF returned the same web hosts in testing, so treat MODERATE as best-effort. | "OFF" |
includePosition | No | boolean, default true | Adds three columns: position (1-indexed, continued across pages, counted after duplicate URLs are removed), pageNumber, and positionOnPage. Turn it off and the three columns are dropped entirely rather than filled with nulls. | true |
watchDomains | No | array (default []) | Hostnames you care about. Enter them bare (example.com), with www., or as a full URL โ all three normalize the same way. Every row gets isWatchedDomain and matchedWatchDomain. The per-keyword best position for each domain is also written to the RANK_SUMMARY record in the run's key-value store. | ["monday.com", "asana.com"] |
onlyWatchedDomains | No | boolean, default false | Push only the results that landed on a watched domain. Positions still show the real SERP position, so a row can legitimately come back as position 7 with nothing above it in the dataset. With this on, maxItems counts results LOOKED AT rather than results saved. | false |
matchSubdomains | No | boolean, default true | On: blog.example.com and docs.example.com match a watch entry of example.com. Off: only the exact host matches (www. is ignored either way). | true |
maxItems | No | integer, default 20, min 1, max 1000 | Hard cap on results per keyword (not per run) โ a 5-keyword job at 20 can save up to 100 rows. Authoritative: the Actor keeps paginating until it reaches this number, hits the optional page cap below, or DuckDuckGo runs out. Duplicate URLs across pages are skipped and do not count. | 20 |
endPage | No | integer, default 0, min 0, max 20 | Optional extra ceiling on result pages fetched per keyword (0 = no page cap, maxItems alone decides). Page sizes: web 10, news ~30, videos ~60 rows. | 0 |
proxyConfiguration | No | object | Optional. When off, the Actor starts direct and automatically escalates to Apify datacenter and then residential proxies if DuckDuckGo blocks an exit IP. Residential is recommended once the keyword list grows past a handful. | {"useApifyProxy": false} |
{"searchKeyword": "project management software","keywordList": ["best crm for agencies","https://duckduckgo.com/?q=task+tracker&kl=de-de"],"searchMode": "default","region": "us-en","safeSearch": "OFF","includePosition": true,"watchDomains": ["monday.com", "asana.com"],"onlyWatchedDomains": false,"matchSubdomains": true,"maxItems": 20,"endPage": 0,"proxyConfiguration": { "useApifyProxy": false }}
Supported URL types and input formats
- Plain keyword:
"project management software"โ searched as-is, using the run'sregionandsafeSearch. - Full DuckDuckGo search URL:
"https://duckduckgo.com/?q=task+tracker&kl=de-de"โ theqparameter is lifted out as the query, and the URL's ownklvalue overrides the run'sregionfor that one keyword only. - Search operators inside a keyword:
"site:example.com filetype:pdf"or"\"exact phrase\""โ passed straight through to DuckDuckGo. watchDomainsentries:"example.com","www.example.com", or"https://example.com/pricing"all normalize to the same host before matching.
Duplicate (keyword, region) pairs across searchKeyword and keywordList are removed automatically.
๐ฆ Output Format
Every row is a flat JSON object pushed to the Actor's default dataset โ one row per search result. Field sets differ by searchMode because web, news and video results carry different base data, but the keyword field and (when enabled) the position and watch columns are added on top of every mode identically.
Output for search results (web mode)
{"query": "project management software","searchMode": "default","title": "The 9 Best Project Management Software Platforms in 2026","url": "https://zapier.com/blog/best-project-management-software/","description": "We tested dozens of project management tools to find the best options for teams of every size.","rawDescription": "We tested dozens of <b>project management</b> tools to find the best options for teams of every size.","hostname": "zapier.com","siteName": "Zapier","canonicalUrl": null,"resultSource": "bingv7aa","faviconUrl": "https://external-content.duckduckgo.com/ip3/zapier.com.ico","keyword": "project management software","position": 3,"pageNumber": 1,"positionOnPage": 3,"isWatchedDomain": false,"matchedWatchDomain": null}
Output for news results
{"query": "apify web scraping","searchMode": "news","title": "How Web Scraping Is Reshaping Competitive Intelligence","url": "https://example-news.com/web-scraping-competitive-intelligence","publisherName": "TechWire","date": 1755302400,"relativeTime": "3d","excerpt": "A look at how data teams are using automated collection to track markets in real time.","rawExcerpt": "A look at how data teams are using automated collection to track markets in <b>real time</b>.","image": "https://example-news.com/images/scraping.jpg","provider": "Bing","isOld": false,"keyword": "apify web scraping","position": 2,"pageNumber": 1,"positionOnPage": 2,"isWatchedDomain": false,"matchedWatchDomain": null}
Output for video results
{"query": "python web scraping tutorial","searchMode": "videos","title": "Python Web Scraping Tutorial for Beginners","url": "https://www.youtube.com/watch?v=abc123","description": "A beginner-friendly walkthrough of building a scraper with Python and requests.","image": "https://i.ytimg.com/vi/abc123/hqdefault.jpg","duration": "18:42","published": "2026-06-02T00:00:00","publisher": "YouTube","uploader": "Corey Schafer","viewCount": 184213,"provider": "youtube","keyword": "python web scraping tutorial","position": 1,"pageNumber": 1,"positionOnPage": 1,"isWatchedDomain": false,"matchedWatchDomain": null}
position, pageNumber and positionOnPage are omitted entirely (not null) when includePosition is off. isWatchedDomain and matchedWatchDomain are omitted entirely when watchDomains is empty โ an unevaluated comparison is not a false.
Two additional records are written to the run's key-value store, not the dataset: RUN_SUMMARY (run-level totals โ keyword count, pages answered, rows saved, duplicates skipped, HTTP requests, JS challenges solved, blocks seen, final proxy tier, runtime) and RANK_SUMMARY (per-keyword rollup โ results scanned, rows saved, and for each watched domain either null or {"bestPosition": ..., "hits": ..., "urls": [...]}).
Schema stability and export options
Field names are stable across runs and are not reshuffled by filtering โ onlyWatchedDomains removes rows but never renumbers or renames the survivors. The default dataset view shows the core rank-checking columns (keyword, position, pageNumber, title, url, hostname, isWatchedDomain, matchedWatchDomain); mode-specific dataset views (full, news, videos) expose the remaining fields for each search mode without changing the underlying row data. Results can be exported as JSON, CSV, Excel, XML or RSS directly from the dataset, or pulled programmatically through the Apify API.
๐ก DuckDuckGo Scraper By Keyword List & Rank Position Strategy Guide
๐ฏ Strategy 1: Real-time enrichment pipeline
Trigger a run from your own backend whenever a new keyword or watch domain enters your system โ a new client onboarding, a new competitor added to a tracking list. Run the Actor with searchKeyword set to the new term and watchDomains set to the client's domains, then read position, isWatchedDomain and matchedWatchDomain straight off the dataset rows and write them back into your CRM or rank-tracking table. No polling loop is needed for a single-keyword check โ the run completes and the dataset is ready to read.
๐ฏ Strategy 2: Scheduled monitoring and alerting
Use an Apify Schedule to run the Actor daily or weekly against a fixed keywordList and watchDomains. After each run, compare RANK_SUMMARY.keywords[].watchedDomains[domain].bestPosition against the previous run's value for the same keyword and domain, and alert when a tracked domain's best position moves by more than your threshold, or flips from a number to null (dropped out of the results scanned entirely).
๐ฏ Strategy 3: Bulk dataset build
Put an entire keyword list โ up to the per-keyword maxItems cap of 1000 โ into keywordList for a single run, and export the resulting dataset to CSV or load it straight into a database via the Apify API. Because each keyword opens its own DuckDuckGo session, cost and runtime scale with list length rather than staying flat, which is the main planning variable for a large one-off research build.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | Onboarding a new keyword or domain on demand | One run per event, triggered from your backend | Dataset rows read back via API |
| Scheduled monitoring | Tracking a fixed keyword/domain list over time | Apify Schedule, run on a cron cadence | RANK_SUMMARY diffed run over run |
| Bulk dataset build | Large one-off keyword-rank research | Single run, large keywordList | Dataset export (CSV/JSON/Excel) |
๐ด Related DuckDuckGo Scrapers & Tools
| Scraper | What it extracts |
|---|---|
Google-Search-Results-Serp-Scraper | Google organic results, ads, People-also-ask and local business packs per query |
Google-Search-Results-Scraper | Google organic SERP results |
Baidu-Search-Scraper | Baidu search results, including paid-ad detection |
This is currently the only DuckDuckGo Actor published under Scrapio. The three listed above cover the same "search results by keyword" entity type on other engines, for teams that need cross-engine rank comparisons alongside DuckDuckGo.
How to integrate DuckDuckGo Scraper By Keyword List & Rank Position with your stack
DuckDuckGo Scraper By Keyword List & Rank Position works with any language or tool that can make an HTTP request, through the Apify API and its official client libraries.
Python
from apify_client import ApifyClientimport csvclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run_input = {"searchKeyword": "project management software","keywordList": ["best crm for agencies", "task tracker app"],"searchMode": "default","region": "us-en","safeSearch": "OFF","watchDomains": ["monday.com", "asana.com"],"maxItems": 20,}run = client.actor("scrapio/duckduckgo-scraper-by-keyword-list-and-rank-position").call(run_input=run_input)rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())fields = ["keyword", "position", "title", "url", "hostname", "isWatchedDomain"]with open("rankings.csv", "w", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=fields)writer.writeheader()for row in rows:writer.writerow({k: row.get(k) for k in fields})
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });const run = await client.actor('scrapio/duckduckgo-scraper-by-keyword-list-and-rank-position').call({searchKeyword: 'project management software',keywordList: ['best crm for agencies', 'task tracker app'],searchMode: 'default',region: 'us-en',watchDomains: ['monday.com', 'asana.com'],maxItems: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) {console.log(row.keyword, row.position, row.hostname, row.isWatchedDomain);}
Async and scheduled pipelines
For recurring rank checks, set up an Apify Schedule against a saved input rather than triggering runs manually. For fire-and-forget large keyword lists, start the run via the API and poll run.status (or configure an Apify webhook on run completion) instead of holding a connection open โ a large keywordList run can take a while since every keyword opens its own DuckDuckGo session.
๐ฏ Who Needs DuckDuckGo Scraper By Keyword List & Rank Position? (Use Cases & Industries)
๐ข SEO agencies and marketing teams
An agency running rank checks for a dozen clients sets watchDomains per client and keywordList to that client's target terms, then reads matchedWatchDomain and position straight into a client report โ no manual SERP screenshots.
๐ AI and data engineering teams
Teams building RAG pipelines or search-behavior datasets pull title, description/excerpt, url and hostname as typed, pre-cleaned text fields, with the rawDescription/rawExcerpt twin available whenever the original markup is needed instead of the cleaned text.
๐ฑ Brand and competitive intelligence teams
Set a competitor's domain as a watchDomains entry and track matchedWatchDomain and bestPosition across a keyword list to see exactly which terms a competitor is winning, and by how many positions.
๐ฌ Researchers
Academic and market researchers use the region parameter to compare DuckDuckGo's public search behavior across locales, working entirely from publicly accessible search result data with no login required.
๐ฅ Product and SaaS builders
Rank-tracking and SEO-monitoring products use the RANK_SUMMARY record as a ready-made backend metric โ best position per domain per keyword โ rather than building that aggregation logic from raw result rows.
Is it legal to scrape DuckDuckGo?
Scraping publicly accessible search results is generally lawful โ DuckDuckGo's SERP is public web data, not a private or authenticated system, and courts have repeatedly distinguished scraping public data from unauthorized computer access. In hiQ Labs, LLC v. LinkedIn Corp. (9th Cir., 2019), the court held that scraping data a website makes publicly accessible does not violate the U.S. Computer Fraud and Abuse Act. Separately, automated querying may conflict with DuckDuckGo's own Terms of Service โ that is a civil contract matter between the user and DuckDuckGo, not a criminal one, and the consequence is typically limited to access being restricted rather than legal liability. DuckDuckGo Scraper By Keyword List & Rank Position returns organic search results, news headlines and video listings โ titles, URLs, hostnames and snippets tied to websites and publishers, not personal profile data about individuals โ so GDPR's personal-data framework does not generally attach to this Actor's output. DuckDuckGo Scraper By Keyword List & Rank Position returns only publicly accessible data. What you do with that data is your responsibility โ consult legal counsel for commercial applications involving personal data.
โ Frequently asked questions
Does DuckDuckGo Scraper By Keyword List & Rank Position work without a DuckDuckGo account?
Yes โ no DuckDuckGo account, login, or API key is required. The Actor authenticates each query the same way a browser does: it fetches DuckDuckGo's public search page and harvests the session tokens (vqd, and dp for web mode) it embeds there before making the actual search request.
How does it handle DuckDuckGo's anti-scraping measures?
Two ways. DuckDuckGo answers a naive request with an inline JavaScript challenge (jsa), which this Actor's solver evaluates deterministically without a browser; a genuine anomaly block is answered by rotating to a fresh exit IP, escalating from a direct connection through Apify datacenter proxies to residential proxies. Web mode and news/video mode also use different HTTP client fingerprints, because DuckDuckGo's endpoints respond differently to each.
Can I run it at scale without getting blocked?
Each keyword opens its own DuckDuckGo session, so scaling up a keyword list increases both cost and the chance of hitting a block, since restarting a session repeatedly is the traffic pattern DuckDuckGo throttles. Enabling residential proxies via proxyConfiguration is recommended once a list grows past a handful of keywords; no fixed run-time or block-rate limit is published beyond that.
How fresh is the data DuckDuckGo Scraper By Keyword List & Rank Position returns?
Every run performs a live fetch against DuckDuckGo โ nothing is cached or reused between runs. Positions are also not tracked historically: each run is independent, and comparing rankings over time means scheduling repeat runs and diffing the resulting datasets yourself.
Which fields work best for AI training and RAG indexing?
For RAG, title plus description (web) or excerpt (news) or description (video) give a clean text passage paired with its url and hostname as the source. For training data, the same fields plus position and searchMode give consistent structure across every record. All fields return as typed primitives โ strings, integers, booleans, or an explicit null โ with no HTML markup to strip before use.
Does it work with Claude, ChatGPT, and other AI agent tools?
Yes, as an HTTP endpoint callable through the Apify API by any agent framework that can make a request and parse JSON โ every field returns typed and pre-cleaned, so no HTML parsing step is needed before passing a row into an LLM context window.
How does DuckDuckGo Scraper By Keyword List & Rank Position compare to other DuckDuckGo scrapers?
As observed on their Apify Store listings on 2026-08-16: jaybird/duckduckgo-scraper (DuckDuckGo SERP Scraper) covers more content types โ web, news, images, videos, suggestions and instant answers โ and also returns a rank field, but its listing doesn't document watched-domain flagging or a rank-rollup record. epctex/duckduckgo-scraper supports images but runs one search term per run and doesn't document a rank/position field. This Actor trades broader content-type coverage for a keyword list plus a purpose-built watch-domain layer in one run.
Why is there no image search mode?
searchMode currently supports web (default), news and videos only โ image search isn't offered in this build.
Why did a result show up at position 7 when only a few rows are in my dataset?
onlyWatchedDomains is on. Positions are the real SERP position and are never renumbered after filtering, so a saved row can legitimately show a position number with nothing above it in the dataset โ the rows above it were scanned and discarded, not skipped.
โน๏ธ Disclaimer
DuckDuckGo Scraper By Keyword List & Rank Position extracts only publicly available data from DuckDuckGo. This tool is intended for lawful use cases only. Users are responsible for complying with DuckDuckGo's terms of service and applicable data protection laws in their jurisdiction.