# DuckDuckGo Scraper — Search Results, Business Leads & News (`yugenox/duckduckgo-scraper`) Actor

Scrape DuckDuckGo web results (up to 1,000 per query), local business leads with phone, website, hours, ratings and review snippets (Yelp and Apple Maps in US/CA, Tripadvisor elsewhere), news, images, videos and stock quotes. No login, no browser.

- **URL**: https://apify.com/yugenox/duckduckgo-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** Lead generation, SEO tools, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 search results

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## DuckDuckGo Scraper: Search Results, Local Business Leads, News, Images & Stock Quotes

Scrape **DuckDuckGo** at scale: organic **web results** (up to 1,000 per query), **local businesses** with phone, website, opening hours, ratings and review snippets, plus **news**, **images**, **videos** and **stock quotes**. One actor covers all of them. It needs no login and no browser, so runs are fast and cheap.

### What you get

| Search type | One row per | Key fields |
|---|---|---|
| **Web** | organic result | rank, page, title, URL, domain, snippet, date, sitelinks, related searches |
| **Places** | local business | name, category, address, phone, website, rating, review count, price level, opening hours, coordinates, listing URL, Yelp ID, Apple Maps ID, menu / order links, review excerpts |
| **News** | article | title, URL, source, snippet, publish date, image |
| **Images** | image | image URL, thumbnail, source page, width × height, format |
| **Videos** | video | URL, title, description, duration, publisher, uploader, view count, publish date, thumbnail |
| **Stock quotes** | ticker | price, change %, open / high / low, previous close, 52-week range, P/E, market cap, average volume, optional intraday series |

#### Places: local business leads

Places search goes beyond the single map panel that other tools stop at. The area is split into map tiles, and busy tiles are split again, so you get **hundreds or thousands of businesses per city** rather than the first 20. In the US and Canada, listings carry Yelp ratings, review counts, price levels and review snippets, merged with Apple Maps. Elsewhere they come from Tripadvisor and Apple Maps. The `dataProvider` field tells you which source each row came from.

Example: 1,000 dentists across Toronto in about a minute. Every row had a phone number, 99% had a website and 97% had opening hours.

### How to use it

1. Enter one or more **search queries**, for example `coffee roasters toronto`.
2. Pick **what to scrape**: Web, Places, News, Images, Videos (you can pick several).
3. For Places, either include the place in the query (`plumber in Vancouver`) or put the business type in the query and the area in **Location** (`Chicago, IL`, `Brooklyn`, `43.65,-79.38,10`).
4. Set **Max results per query** and run.

#### Input example: web results for SEO rank tracking

```json
{
  "queries": ["best crm for small business", "project management software"],
  "searchTypes": ["web"],
  "region": "us-en",
  "maxResultsPerQuery": 100,
  "includeRelatedSearches": true
}
```

#### Input example: local leads

```json
{
  "queries": ["dentist", "orthodontist"],
  "searchTypes": ["places"],
  "location": "Toronto, ON",
  "maxResultsPerQuery": 500
}
```

#### Input example: stock quotes

```json
{
  "stockSymbols": ["AAPL", "MSFT", "NVDA", "SPY", ".DJI"],
  "includeFundamentals": true
}
```

#### Reliability and billing

- Runs never fail on data problems. If DuckDuckGo rate-limits, changes a page format, or the run hits its time limit, you get everything collected so far and a status message that says what happened (`Done`, `Partial — stopped at …`, or `0 results, no charge`).
- You are charged only for rows written to the dataset: `result` (web, news, image, video), `place`, and `stock-quote`. Stock symbols DuckDuckGo does not know come back as an error row that is not charged.
- Datacenter proxies are used by default. If they keep getting rate-limited, the run continues on residential proxies; set `residentialFallback` to `false` to stay on datacenter only.
- Common input names from other scrapers are accepted (`query`, `searchQueries`, `keywords`, `maxResults`, `limit`, `location`/`where`, `tickers`, `locale`), so existing inputs usually work unchanged.

### Output examples

**Web result**

```json
{
  "type": "web",
  "query": "coffee roasters toronto",
  "region": "us-en",
  "rank": 5,
  "page": 1,
  "position": 5,
  "title": "Toronto's best coffee roasters - Toronto Life",
  "url": "https://torontolife.com/food/torontos-best-coffee-roasters/",
  "displayUrl": "torontolife.com/food/torontos-best-coffee-roasters/",
  "domain": "torontolife.com",
  "siteName": "Toronto Life",
  "description": "Enter some of the best beans from Toronto's top roasters. Here, our favourite places to scoop up single-origin specimens and balanced blends.",
  "date": null,
  "sitelinks": [],
  "richSnippet": null,
  "relatedSearches": null,
  "scrapedAt": "2026-09-24T11:33:22.909Z"
}
```

**Place**

```json
{
  "type": "place",
  "query": "coffee roasters toronto",
  "location": "toronto",
  "rank": 1,
  "name": "Outpost Coffee Roasters",
  "category": "Coffee roasteries",
  "address": "1578 Bloor Street W, Toronto, ON M6P 1A4",
  "city": "Toronto",
  "countryCode": "CA",
  "latitude": 43.656143,
  "longitude": -79.454102,
  "phone": "+1 416 516 9040",
  "website": "https://outpostcoffee.com",
  "rating": 4.5,
  "reviewCount": 86,
  "priceLevel": 2,
  "openingHours": { "Mon": "07:30-17:30", "Tue": "07:30-17:30", "Wed": "07:30-17:30" },
  "dataProvider": "Yelp",
  "providerUrl": "https://www.yelp.ca/biz/outpost-coffee-roasters-toronto",
  "yelpBusinessId": "xvp1GmKW-LAllqL5IYw2ew",
  "applePlaceId": "9671331448292176295",
  "menuUrl": "https://outpostcoffee.com/pages/menu-1578-bloor-st-w",
  "reviewExcerpts": [
    { "text": "Amazing coffee! They even grind their own beans and sell them…", "rating": 5, "date": "2022-01-25T15:47:51.000Z" }
  ]
}
```

**Stock quote**

```json
{
  "type": "stock",
  "symbol": "NVDA",
  "companyName": "NVIDIA Corp",
  "latestPrice": 225.51,
  "change": -3.36,
  "changePercent": -1.4681,
  "open": 228.03,
  "high": 228.95,
  "low": 224.02,
  "week52High": 236.54,
  "week52Low": 164.27,
  "peRatio": 28.5068,
  "marketCap": 5515767000000,
  "avgTotalVolume": 127677727,
  "currency": "USD",
  "exchange": "NSQ",
  "latestUpdate": "2026-09-23T20:00:00.000Z"
}
```

Every row has a `type` field (`web`, `place`, `news`, `image`, `video`, `stock`), so one dataset can hold several search types. The dataset has ready-made table views for web and news, places, media, and stocks.

### Inputs

| Field | What it does |
|---|---|
| `queries` | Search terms, one per line. |
| `searchTypes` | Any of `web`, `places`, `news`, `images`, `videos`. Default `web`. |
| `maxResultsPerQuery` | Per query and type. Web, news, images and videos: up to 1,000. Places: up to 5,000. Default 50. |
| `location` | Places only. A city, area or address, or `lat,lng`, `lat,lng,radiusKm`, or a box `north,west,south,east`. Leave it empty to read the place from the query. |
| `region` | Result country and language (`us-en`, `ca-en`, `uk-en`, `de-de`, `fr-fr`, `in-en`, …). Default `us-en`. |
| `timeRange` | `day`, `week`, `month` or `year`. For web, news, images and videos. |
| `safeSearch` | `moderate` (default), `strict` or `off`. |
| `includeRelatedSearches` | Adds related searches to the first web result of each query. |
| `stockSymbols` | Tickers for stock quotes (runs alongside or instead of queries). |
| `includeFundamentals` / `includeIntraday` | Market cap and average volume, and a minute-by-minute intraday series. |
| `maxItems` | Cap for the whole run (0 = no cap). |
| `maxConcurrency` | Parallel requests (default 10). |
| `proxyConfiguration` | Apify Proxy. Datacenter works; the actor switches to residential proxies automatically if it has to. |

### Use cases

- **SEO rank tracking:** where a domain ranks for a keyword, by region, down to position 1,000.
- **Lead generation:** local businesses with phone, website, hours and ratings, city by city.
- **Market research:** how many competitors are in an area, and how they are rated and priced.
- **News monitoring:** fresh articles for a brand or topic, filtered to the past day or week.
- **Dataset building:** images and videos for a topic, with dimensions and source pages.
- **Price snapshots:** end-of-day or intraday quotes for a watch list.

### FAQ

**Do I need a DuckDuckGo account or API key?**
No. Nothing to set up. Enter your queries and run.

**How many web results can I get per query?**
Up to about 1,000. DuckDuckGo stops serving results beyond that. Very specific queries run out sooner, and the run stops cleanly when there are no more pages.

**Where does places data come from?**
DuckDuckGo's own maps results. In the US and Canada they are Yelp listings merged with Apple Maps, including rating, review count, price level, Yelp ID and review snippets. In other countries they come from Tripadvisor and Apple Maps, so ratings and review snippets are less common, and phone and website coverage varies by city. `dataProvider` shows the source of each row.

**Are reviewer names included?**
No. Review excerpts include only the text, star rating and date.

**Which stock symbols work?**
US-listed stocks and ETFs (AAPL, MSFT, SPY, QQQ…) and the indices `.DJI`, `.IXIC`, `.GSPTSE`, `.GDAXI` and `.FTSE`. Unknown symbols return a row with an `error` message and are not counted as results.

**What happens if a run is slowed down or blocked?**
The actor spreads requests across many IP addresses and switches to residential proxies by itself if it has to. If it still cannot get results, it finishes with a clear status message and 0 results, and you are not charged for anything.

**Can I run it on a schedule or through the API?**
Yes. Schedule it in Apify Console, or call it from the Apify API, Make, Zapier or n8n and read the dataset as JSON, CSV or Excel.

**Is it legal to scrape DuckDuckGo?**
This actor collects only publicly available data: the same results, business listings and quotes anyone sees on DuckDuckGo without logging in. Results can still contain personal data, such as a person named in a search result or the phone number of a sole-proprietor business, so make sure your use of the data follows data-protection laws such as GDPR, PIPEDA and CCPA, as well as DuckDuckGo's terms. If you are unsure, check with a lawyer. For more background, read [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. The actor uses no account, login or cookies, so it can only see what DuckDuckGo shows every visitor. It does not collect reviewer names, profiles or photos: review excerpts carry only the text, star rating and date.

# Actor input Schema

## `queries` (type: `array`):

What to search, one per line — exactly as you would type it into DuckDuckGo. For places, a business type plus a place works on its own ("dentist in Toronto"), or put the business type here and the area in "Location".

## `searchTypes` (type: `array`):

Pick one or more. Every query runs once per selected type. Web = organic results; Places = local businesses with phone, website, hours, rating and reviews; News, Images and Videos = the matching DuckDuckGo tabs.

## `maxResultsPerQuery` (type: `integer`):

Per query and per search type. Web, news, images and videos go up to 1,000; places up to 5,000 (large areas are covered tile by tile).

## `location` (type: `string`):

Area to search for places: a city, neighbourhood, region or address ("Chicago, IL", "Paris 11e", "Brooklyn"), or coordinates: "lat,lng" (5 km around), "lat,lng,radiusKm", or a box "north-lat,west-lng,south-lat,east-lng". Leave empty to take the place from each query ("plumber in Vancouver"). Only used by Places.

## `region` (type: `string`):

Country / language of the results (DuckDuckGo region setting). Used by web, news, images and videos.

## `timeRange` (type: `string`):

Only results from the past day / week / month / year (web, news, images, videos).

## `safeSearch` (type: `string`):

Adult-content filter (web, news, images, videos).

## `includeRelatedSearches` (type: `boolean`):

Adds DuckDuckGo's "related searches" to the first web result of each query (field relatedSearches).

## `stockSymbols` (type: `array`):

Optional. Ticker symbols for live quotes (price, change, day range, 52-week range, P/E, market cap, average volume). Covers US-listed stocks and ETFs (AAPL, MSFT, SPY…) plus the indices .DJI, .IXIC, .GSPTSE, .GDAXI and .FTSE. Runs independently of the queries.

## `includeFundamentals` (type: `boolean`):

One extra lookup per symbol.

## `includeIntraday` (type: `boolean`):

Adds the latest session's minute-by-minute prices (≈390 points) to each quote.

## `maxItems` (type: `integer`):

Stop the whole run after this many results (0 = no limit).

## `maxConcurrency` (type: `integer`):

Parallel requests. The default is a good balance; higher values mostly help big places runs.

## `proxyConfiguration` (type: `object`):

Datacenter proxies work and are the cheapest; the actor switches to residential proxies automatically if it has to.

## `residentialFallback` (type: `boolean`):

When datacenter IPs keep getting rate-limited, finish the run on Apify residential proxies (billed per GB on your account, usually a few MB). Turn off to stay on datacenter proxies only.

## Actor input object example

```json
{
  "queries": [
    "coffee roasters toronto"
  ],
  "searchTypes": [
    "web",
    "places"
  ],
  "maxResultsPerQuery": 20,
  "region": "us-en",
  "timeRange": "",
  "safeSearch": "moderate",
  "includeRelatedSearches": false,
  "includeFundamentals": true,
  "includeIntraday": false,
  "maxItems": 0,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true
}
```

# Actor output Schema

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

All scraped results.

## `run` (type: `string`):

Status and statistics for this run.

# 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 = {
    "queries": [
        "coffee roasters toronto"
    ],
    "searchTypes": [
        "web",
        "places"
    ],
    "maxResultsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/duckduckgo-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 = {
    "queries": ["coffee roasters toronto"],
    "searchTypes": [
        "web",
        "places",
    ],
    "maxResultsPerQuery": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "coffee roasters toronto"
  ],
  "searchTypes": [
    "web",
    "places"
  ],
  "maxResultsPerQuery": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/duckduckgo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/duckduckgo-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/R4wB2Hlg8AhSXC5Ur/builds/rv7cd05urTsyMDN6u/openapi.json
