# Aldi Weekly Ad Scraper (`crawloop/aldi-weekly-ad-scraper`) Actor

Scrape ALDI US weekly ads and ALDI Finds by ZIP code. Export sale price, regular price, brand, size, stock, and images from the public circular — an Aldi weekly ad API alternative for Python, Node.js, and MCP.

- **URL**: https://apify.com/crawloop/aldi-weekly-ad-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 weekly ad offers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Aldi Weekly Ad Scraper — ZIP Grocery Prices

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by ALDI or Instacart. Data is read from publicly accessible aldi.us circular pages only. No login. You are responsible for complying with applicable law and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

This **Aldi weekly ad scraper** turns the public US **weekly circular** and **ALDI Finds** flyer into a structured Apify dataset, scoped to a store **ZIP code**. Export **sale price**, **regular price**, **brand**, **size**, **stock**, and **images** as JSON or CSV — an Aldi weekly ad API alternative for **Python**, **Node.js**, and **MCP**.

It is **not** a full 13k-SKU grocery catalog. Pair it with a marketplace scraper when you need online comps rather than ZIP-local advertised specials.

| Grocery weekly ads | US mass retail | EU Lidl leaflets | Marketplace comps |
| :--- | :--- | :--- | :--- |
| **Aldi Weekly Ad Scraper** ◄── you are here | [Walmart Scraper](https://apify.com/crawloop/walmart-scraper) | [Lidl Weekly Offers Scraper](https://apify.com/crawloop/lidl-weekly-offers-scraper) | [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) · [Tractor Supply Product Scraper](https://apify.com/crawloop/tractor-supply-product-scraper) |

***

### When to use this Actor

- **Aldi weekly ad scrape** for one US ZIP (this week’s sale circular / flyer)
- **ALDI Finds scraper** for limited-run SKUs, plus an optional next-week preview
- **Grocery price monitoring** on advertised ALDI prices, percent-off badges, and unit price
- **Deal aggregators / meal-planning** feeds that need ZIP-local ALDI offers
- **CPG / private-label research** on ALDI exclusive brands in the circular
- **Scheduler jobs** that refresh after Wednesday when the new ad drops

### When not to use this Actor

- **Full aisle catalog dumps** — this Actor is the weekly circular, not every SKU
- **Aldi Australia, UK, Ireland, or Germany** (Nord/Süd / Hofer) — US `aldi.us` only
- **Checkout, cart, Instacart account, or login** automation
- **Store-locator crawls as a primary job** — pass a ZIP; the Actor resolves the store
- **Amazon search** — use [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper)

***

### Key Features

- **ZIP-scoped grocery prices** — ALDI US prices differ by store; every row is stamped with ZIP, store name, city, and state
- **Weekly ad + ALDI Finds** — sale circular (~150–250 items) and limited-run Finds, including next-week preview when published
- **Sale fields** — current price, regular price, dollar off, percent off, unit price, on-sale flag
- **Stock + images** — ZIP-local availability, product URL, and primary image
- **Fast HTTP** — public storefront JSON via Chrome TLS impersonation; no headless browser
- **Simple input** — ZIP in, offers out; optional keyword and price filters

***

### Use Cases

| Use case | What you get | Why it helps |
| :--- | :--- | :--- |
| **Weekly ad tracker** | `price`, `regularPrice`, `discountPercent`, `week` | Refresh the circular after Wednesday |
| **ZIP comparison** | `zipCode`, `storeId`, `storeName` | Same SKU, different stores |
| **ALDI Finds calendar** | `isAldiFinds`, `collection`, next-week toggle | Limited-run SKUs that rotate weekly |
| **Deal / meal-planning apps** | Title, brand, size, image, product URL | Populate a grocery deals feed |
| **Private-label research** | `isStoreBrand`, `brand`, dietary badges | Track exclusive brands on promotion |

***

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `zipCode` | String | `60174` | Required 5-digit US ZIP |
| `includeThisWeek` | Boolean | `true` | This week’s weekly ad (sale circular) |
| `includeAldiFinds` | Boolean | `true` | This week’s ALDI Finds |
| `includeNextWeek` | Boolean | `false` | Upcoming ALDI Finds preview |
| `keyword` | String | empty | Optional title/brand substring filter |
| `minPrice` / `maxPrice` | Number | — | USD shelf-price bounds |
| `onSaleOnly` | Boolean | `false` | Keep rows marked as sale vs regular |
| `maxItems` | Integer | `200` | Max dataset rows; `0` = all selected circulars |
| `requestDelaySecs` | Number | `0.2` | Delay between HTTP requests |
| `proxyConfiguration` | Object | US proxy | Apify Proxy — US recommended |

#### Input Example — this week’s ad + Finds

```json
{
  "zipCode": "60174",
  "includeThisWeek": true,
  "includeAldiFinds": true,
  "includeNextWeek": false,
  "maxItems": 200
}
```

#### Input Example — next-week Finds preview

```json
{
  "zipCode": "10001",
  "includeThisWeek": false,
  "includeAldiFinds": false,
  "includeNextWeek": true,
  "maxItems": 0
}
```

#### Input Example — keyword filter

```json
{
  "zipCode": "60174",
  "keyword": "milk",
  "onSaleOnly": true,
  "maxItems": 50
}
```

***

### Output Format

Each dataset row is one circular offer at the requested ZIP.

| Field | Type | Description |
| :--- | :--- | :--- |
| `productId` | String | ALDI product id |
| `title` | String | Product name |
| `brand` | String | Brand (null when the circular omits it) |
| `isStoreBrand` | Boolean | ALDI exclusive label |
| `size` / `unit` | String | Pack size / pricing unit |
| `price` | Number | Current USD price |
| `regularPrice` | Number | Pre-sale price when discounted |
| `discount` / `discountPercent` | Number | Dollar off / percent off |
| `pricePerUnit` | String | Unit-price string when shown |
| `isOnSale` | Boolean | Sale badge or regular > current |
| `inStock` / `stockLevel` | Boolean / String | ZIP-scoped availability |
| `collection` | String | `weekly-specials`, `aldi-finds`, or `upcoming-aldi-finds` |
| `week` | String | `this_week` or `next_week` |
| `isAldiFinds` | Boolean | Finds circular |
| `zipCode` | String | Requested ZIP |
| `storeId` / `storeName` | String | Resolved ALDI location |
| `storeCity` / `storeState` | String | City and state |
| `productUrl` | String | Public product URL |
| `imageUrl` | String | Primary image |
| `dietaryAttributes` | Array | Storefront badges |
| `scrapedAt` | String | UTC timestamp |

#### Output Example

```json
{
  "source": "aldi.us",
  "productId": "19115493",
  "title": "USDA Choice Black Angus Petite Sirloin Steak, per lb",
  "brand": null,
  "isStoreBrand": false,
  "price": 11.69,
  "regularPrice": 12.99,
  "discount": 1.3,
  "discountPercent": 10,
  "priceCurrency": "USD",
  "isOnSale": true,
  "inStock": true,
  "collection": "weekly-specials",
  "week": "this_week",
  "isAldiFinds": false,
  "zipCode": "60174",
  "storeId": "20785",
  "storeName": "ALDI - BAT 43 - St. Charles",
  "productUrl": "https://www.aldi.us/store/aldi/products/19115493-black-angus-choice-petite-sirloin-steak-per-lb",
  "scrapedAt": "2026-09-20T13:03:42Z"
}
```

***

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/aldi-weekly-ad-scraper').call({
  zipCode: '60174',
  includeThisWeek: true,
  includeAldiFinds: true,
  maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_TOKEN")
run = client.actor("crawloop/aldi-weekly-ad-scraper").call(run_input={
    "zipCode": "60174",
    "includeThisWeek": True,
    "includeAldiFinds": True,
    "maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("title"), item.get("price"), item.get("zipCode"))
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/crawloop~aldi-weekly-ad-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"zipCode":"60174","includeThisWeek":true,"includeAldiFinds":true,"maxItems":50}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call this Actor by its Store ID `crawloop/aldi-weekly-ad-scraper`.

Example prompts:

- "Run Aldi Weekly Ad Scraper for ZIP 60174 and return the top 20 sale rows as JSON"
- "Scrape this week's ALDI Finds for ZIP 10001 and summarize brands, prices, and percent off"
- "Chain Aldi Weekly Ad Scraper then [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) to compare an ALDI Finds SKU vs Amazon listings"

### Suite next step

After ZIP-local ALDI circular prices, run [Walmart Scraper](https://apify.com/crawloop/walmart-scraper) for ZIP-local mass-retail comps, [Lidl Weekly Offers Scraper](https://apify.com/crawloop/lidl-weekly-offers-scraper) for European Lidl leaflets, [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) for online comps on the same SKUs, or [Tractor Supply Product Scraper](https://apify.com/crawloop/tractor-supply-product-scraper) for US rural-retail catalog prices.

### FAQ

**Why do I have to pass a ZIP?**\
ALDI US prices and assortment are store-specific. A price without a store is not a fact. The ZIP selects the store; it is not a post-filter.

**Weekly ad vs ALDI Finds?**\
The weekly ad is the sale circular (`collection=weekly-specials`). ALDI Finds are limited-run items for the current week. Toggle `includeNextWeek` for the preview when ALDI has published it (typically Wednesday).

**Can I scrape Aldi with Python or Node.js?**\
Yes. Use the Apify client examples above, or call the Actor from an AI assistant via MCP. The dataset is JSON — title, sale price, regular price, brand, size, stock, ZIP, and product URL.

**What if the ZIP has no nearby store?**\
The run fails with a clear status message. No offer rows are written.

**Is this the full grocery catalog?**\
No. It is the circular (plus Finds). Keyword search across every SKU is out of scope.

**Are filtered-out rows charged as results?**\
No. Only dataset offers that pass your keyword / price / sale filters are charged as results.

**US only?**\
Yes. This Actor reads the public US storefront. Other country catalogs are out of scope.

### Related Actors

- [Lidl Weekly Offers Scraper](https://apify.com/crawloop/lidl-weekly-offers-scraper)
- [Walmart Scraper](https://apify.com/crawloop/walmart-scraper)
- [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper)
- [Tractor Supply Product Scraper](https://apify.com/crawloop/tractor-supply-product-scraper)
- [Etsy Scraper](https://apify.com/crawloop/etsy-scraper)
- [888lots Scraper](https://apify.com/crawloop/888lots-scraper)

### Notes

- Prefer **US Apify Proxy**. Switch to RESIDENTIAL US if GraphQL returns 403.
- Circulars usually refresh **Wednesday**. Next-week Finds can be empty earlier in the week.
- Duplicate products that appear in both the weekly ad and ALDI Finds keep the Finds row.
- Some weekly-ad rows omit `brand`; title, price, and product URL still populate.

# Actor input Schema

## `zipCode` (type: `string`):

5-digit ZIP of the ALDI store to price. Weekly-ad prices and assortment are store-specific.

## `includeThisWeek` (type: `boolean`):

Sale circular for the store (typically 150–250 items).

## `includeAldiFinds` (type: `boolean`):

Limited-run ALDI Finds for the current week.

## `includeNextWeek` (type: `boolean`):

Preview circular for next week's ALDI Finds when published (usually Wednesday).

## `keyword` (type: `string`):

Optional case-insensitive substring on product title or brand. Leave empty for the full circular.

## `minPrice` (type: `number`):

Keep offers at or above this shelf price.

## `maxPrice` (type: `number`):

Keep offers at or below this shelf price.

## `onSaleOnly` (type: `boolean`):

Drop rows that are not marked as a sale vs regular price.

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

Stop after this many dataset rows. Use 0 for every item in the selected circulars.

## `requestDelaySecs` (type: `number`):

Pause between HTTP calls on the sticky session.

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

Apify Proxy. US datacenter is the default; switch to RESIDENTIAL US if GraphQL returns 403.

## Actor input object example

```json
{
  "zipCode": "60174",
  "includeThisWeek": true,
  "includeAldiFinds": true,
  "includeNextWeek": false,
  "onSaleOnly": false,
  "maxItems": 200,
  "requestDelaySecs": 0.2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

Default dataset items.

# 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 = {
    "zipCode": "60174",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/aldi-weekly-ad-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 = {
    "zipCode": "60174",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/aldi-weekly-ad-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 '{
  "zipCode": "60174",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}' |
apify call crawloop/aldi-weekly-ad-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/aldi-weekly-ad-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/Kx50c3lqDu71dZJVE/builds/mqteLaVdN2Pcwzycg/openapi.json
