# Abt Electronics Scraper (`crawlerbros/abt-electronics-scraper`) Actor

Scrape Abt.com - a major US electronics & appliance retailer. Search by keyword, browse computers/TVs/audio/gaming/camera categories, or fetch specific products by URL or SKU. Get price, brand, SKU/model/MPN, availability, images, description and dimensions.

- **URL**: https://apify.com/crawlerbros/abt-electronics-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Abt Electronics Scraper

Scrape **Abt.com** — a major US electronics and appliance retailer (Glenview, IL, family-owned since 1936) with openly displayed pricing and stock status. Search by keyword, browse curated computer/TV/audio/gaming/camera/networking categories, or fetch specific products by URL or SKU. Get price, brand, SKU/model/MPN, availability, images, description and dimensions. No login, no cookies, no proxy required.

### What this actor does

- **Three modes:** `search` (keyword search), `byCategory` (browse a curated department), `byUrl` (direct product URL or bare SKU/ID lookup)
- **88 categories** across computers/tablets, TVs & home theater, home & car audio, headphones, cameras & camcorders, gaming, networking, and wearables
- **Filters:** minimum/maximum price, brand contains, in-stock only
- **Client-side sort:** relevance (site order), price low-to-high/high-to-low, name A-Z/Z-A
- **`fetchFullDetails`:** opt in (mode=search/byCategory) to fetch each result's product-detail page for the full field set (sku, mpn, gtin, availability, condition, dimensions, etc.) at the cost of a slower per-product Playwright fetch; `mode=byUrl` always returns full details
- **Empty fields are omitted** — a field only appears on a record when Abt actually published a value for it

### Output per product

- `title` — full product name
- `brand`, `brandUrl`
- `sku`, `model`, `mpn`, `gtin`, `productId` — Abt's own model/part numbers
- `price`, `currency`, `currencySymbol`
- `originalPrice`, `savings`, `discountPercent` — Abt's list/MSRP price and the discount off it, when the item is marked down (omitted when Abt sells it at its list price)
- `availability` (`InStock` / `OutOfStock`), `inStock` (boolean), `availabilityText` (Abt's own stock-status label)
- `condition` — `NewCondition` / `RefurbishedCondition` / etc.
- `color`
- `description`
- `quickFeatures[]` — short bullet spec highlights shown on the listing card
- `category`, `categoryPath[]` — breadcrumb trail
- `images[]`, `mainImageUrl`, `thumbnailUrl`
- `heightIn`, `widthIn`, `depthIn`, `weightLb` — physical dimensions, when Abt publishes them
- `sellerName`, `returnPolicyDays`
- `freeShipping` — `true` when the listing shows a free-shipping badge
- `sourceUrl` — canonical Abt.com product URL
- `recordType: "product"`, `scrapedAt`

**Note:** `sku`, `mpn`, `gtin`, `availability`/`inStock`, `condition`, `description`, `images[]`, dimensions/weight, `originalPrice`/`savings`/`discountPercent`, `categoryPath[]`, `sellerName` and `returnPolicyDays` come from the product-detail page. `mode=byUrl` always includes them. `mode=search`/`byCategory` only include them when `fetchFullDetails` is enabled — by default those modes return the faster listing-page field set (`title`, `price`, `brand`, `model`, `quickFeatures[]`, `thumbnailUrl`, `availabilityText`, `freeShipping`).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byCategory` / `byUrl` |
| `searchQuery` | string | `bluetooth speaker` | Free-text keyword search (mode=search) |
| `categoryId` | string (select) | `415` (Laptops & Notebook Computers) | Curated Abt category (mode=byCategory) |
| `productUrls` | array | – | Abt product URLs or bare SKU/ID numbers (mode=byUrl) |
| `minPrice` | int | – | Drop products priced below this amount (USD) |
| `maxPrice` | int | – | Drop products priced above this amount (USD) |
| `brand` | string | – | Keep only products whose brand contains this text |
| `inStockOnly` | boolean | `false` | Keep only products Abt currently lists as in stock |
| `fetchFullDetails` | boolean | `false` | (mode=search/byCategory) Fetch each result's detail page for the full field set, slower per product |
| `sortBy` | string (select) | `relevance` | `relevance` / `priceAsc` / `priceDesc` / `nameAsc` / `nameDesc` |
| `maxItems` | int | `20` | Hard cap on emitted records (1–500) |

#### Example: keyword search

```json
{
  "mode": "search",
  "searchQuery": "bluetooth speaker",
  "maxItems": 20
}
```

#### Example: browse a category with a price ceiling

```json
{
  "mode": "byCategory",
  "categoryId": "2804",
  "maxPrice": 150,
  "inStockOnly": true,
  "sortBy": "priceAsc",
  "maxItems": 50
}
```

#### Example: filter search results to one brand

```json
{
  "mode": "search",
  "searchQuery": "4k tv",
  "brand": "Samsung",
  "sortBy": "priceDesc",
  "maxItems": 30
}
```

#### Example: lookup specific products by URL or SKU

```json
{
  "mode": "byUrl",
  "productUrls": [
    "https://www.abt.com/LG-18-000-BTU-11.9-EER-230-208V-Smart-Window-Air-Conditioner-LW1821ERSM/p/156637.html",
    "232163"
  ]
}
```

### Use cases

- **Price monitoring** — track a category or a watch-list of SKUs for price/stock changes over time
- **Market research** — compare brand assortment and pricing across electronics categories
- **Competitive intelligence** — benchmark a retailer's catalog breadth against your own
- **Deal alerting** — combine `maxPrice` + `inStockOnly` to surface in-budget, in-stock items
- **Catalog enrichment** — pull structured product data (brand, model, MPN, dimensions) for cross-referencing

### FAQ

**Is this affiliated with Abt Electronics?**
No. This is an independent, third-party actor that reads Abt.com's publicly served product pages. It is not affiliated with or endorsed by Abt Electronics Inc.

**Does Abt.com require a store or ZIP code to see prices?**
No. Unlike some regional/warehouse retailers, Abt shows price and stock status to anonymous visitors without requiring a store or ZIP selection, so results are consistent regardless of location.

**Does this show discounts / list price?**
Yes. When Abt marks an item down from its list price (MSRP), the record includes `originalPrice` (the list price), `savings` (dollar amount off) and `discountPercent`. These three fields are omitted when Abt is currently selling the item at its list price — there's no discount to report.

**Are ratings and review counts available?**
Not currently. Abt renders its star ratings and review counts through a client-side JavaScript widget that isn't present in the page's initial HTML, so this actor doesn't expose `rating`/`reviewCount` fields rather than emit unreliable data.

**Why does `search` mode cap out around 20 results even with a higher `maxItems`?**
Abt.com's own keyword-search results page does not paginate past its first ~20 matches through any publicly available parameter — its "page 2, 3, ..." links are wired to a script that Abt explicitly disables on the search-results page itself. This is a genuine limitation of Abt's search endpoint, not a limit imposed by this actor. `byCategory` mode does not have this limitation — Abt's category browse pages paginate correctly through their full catalog, so use `byCategory` (optionally combined with `brand`) when you need more than ~20 results for a given department.

**Why does a single-word search sometimes return nothing?**
When a `searchQuery` strongly matches one department (e.g. `laptop`, `tv`), Abt redirects the search straight to that department's browse landing page rather than a search-results list, and a couple of Abt's top-level department landing pages don't carry a product grid of their own. Use a more specific query (`bluetooth speaker`, `gaming laptop`) or switch to `byCategory` mode with a specific category instead.

**Why isn't there a `sortBy` value that changes what Abt itself returns?**
Abt's own sort query parameter doesn't affect its server-rendered listing pages. `sortBy` is applied to the collected batch of results instead, which is fully reliable and deterministic.

**What categories are covered?**
Abt sells appliances, furniture and mattresses in addition to electronics. This actor's `categoryId` dropdown is curated to Abt's electronics-relevant departments — computers & tablets, TVs & home theater, home & car audio, headphones, cameras & camcorders, gaming, networking, and wearables.

**How fresh is the data?**
Every run reads Abt.com live — prices and stock status reflect what's published at run time.

**Can I look up a product by just its SKU number?**
Yes. In `byUrl` mode, `productUrls` accepts either a full Abt product URL or a bare numeric SKU/ID (e.g. `156637`), which Abt resolves to the correct product page.

**Why do some runs take a bit longer than a typical scraper?**
Abt.com actively challenges automated traffic. This actor clears that challenge automatically on every request, which adds a few seconds per product compared to a plain HTTP fetch — a 20-product search typically completes in under 3 minutes.

**Why do some products have fewer fields than others?**
Fields are only included when Abt actually publishes a value — for example, not every product has published physical dimensions, or a `mpn` distinct from its `sku`. Empty fields are omitted rather than sent as `null`.

**Why don't my `search`/`byCategory` results include `sku`/`availability`/`condition`/dimensions?**
Those fields live on the product-detail page, not the listing page. Set `fetchFullDetails: true` to fetch each result's detail page for the complete field set — it's off by default because Abt serves a Cloudflare challenge on every detail page that costs an extra ~10-17s per product to clear. `mode=byUrl` always fetches the detail page, so it always returns the full field set regardless of this setting.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `searchQuery` (type: `string`):

Free-text keyword search, e.g. `bluetooth speaker`, `samsung tv 55`, `wireless mouse`. Avoid single generic department words (e.g. `laptop`, `tv`) — Abt redirects a single strong category match straight to that department's browse page instead of a search-results list.

## `categoryId` (type: `string`):

Browse a curated Abt electronics/computers/gaming/audio/camera/networking category.

## `productUrls` (type: `array`):

Full Abt.com product URLs (e.g. `https://www.abt.com/.../p/156637.html`) or bare Abt SKU/product IDs (e.g. `156637`).

## `minPrice` (type: `integer`):

Drop products priced below this amount.

## `maxPrice` (type: `integer`):

Drop products priced above this amount.

## `brand` (type: `string`):

Keep only products whose brand name contains this text (case-insensitive), e.g. `LG`, `Samsung`, `Sony`.

## `inStockOnly` (type: `boolean`):

Keep only products Abt currently lists as in stock.

## `fetchFullDetails` (type: `boolean`):

When enabled, each search/category result is also fetched from its product-detail page for the full field set (sku, model, mpn, gtin, availability, condition, description, images, dimensions, weight, originalPrice/savings/discountPercent, categoryPath). Off by default because Abt serves a Cloudflare challenge on every product-detail page that only a Playwright navigation can clear (~10-17s per product); with this off, search/byCategory records carry the faster listing-page field set (title, price, brand, model, quickFeatures, thumbnailUrl, availabilityText). mode=byUrl always fetches full details regardless of this setting.

## `sortBy` (type: `string`):

Client-side sort applied to the collected results (Abt's own sort parameter does not affect its server-rendered listing pages).

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

Hard cap on emitted product records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "bluetooth speaker",
  "categoryId": "415",
  "productUrls": [],
  "inStockOnly": false,
  "fetchFullDetails": false,
  "sortBy": "relevance",
  "maxItems": 20
}
```

# Actor output Schema

## `products` (type: `string`):

Dataset containing all scraped Abt.com products.

# 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 = {
    "mode": "search",
    "searchQuery": "bluetooth speaker",
    "categoryId": "415",
    "productUrls": [],
    "inStockOnly": false,
    "fetchFullDetails": false,
    "sortBy": "relevance",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/abt-electronics-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 = {
    "mode": "search",
    "searchQuery": "bluetooth speaker",
    "categoryId": "415",
    "productUrls": [],
    "inStockOnly": False,
    "fetchFullDetails": False,
    "sortBy": "relevance",
    "maxItems": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "mode": "search",
  "searchQuery": "bluetooth speaker",
  "categoryId": "415",
  "productUrls": [],
  "inStockOnly": false,
  "fetchFullDetails": false,
  "sortBy": "relevance",
  "maxItems": 20
}' |
apify call crawlerbros/abt-electronics-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/abt-electronics-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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