# Yodobashi Scraper: Prices, Points, Specs & Reviews (`abotapi/yodobashi-com-scraper`) Actor

Scrape yodobashi.com electronics and appliances: JPY price, list price and discount, reward points, stock and delivery, images, specifications, variants and customer reviews. Search by keyword with the store's own category, brand, price and sort filters, or paste product, category and search URLs.

- **URL**: https://apify.com/abotapi/yodobashi-com-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product results

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?

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

## Yodobashi.com Scraper

Structured product data from **[Yodobashi.com](https://www.yodobashi.com/)**, Japan's largest
electronics and appliance retailer: price, list price and discount, Gold Point reward value, stock
and delivery, images, full specifications, variants and customer reviews.

Search by keyword with the store's own filters, or paste product, category, brand and search URLs
and get back the products they hold.

***

### What you get

| Group | Fields |
|---|---|
| **Identity** | `sku` (Yodobashi's own product id), `url`, `title`, `brand`, `makerName`, `makerId`, `categoryBreadcrumb`, `categoryUrl`, `categoryCode`, `releaseDate` |
| **Price** | `price`, `listPrice`, `discountAmount`, `discountPercent`, `discountNote`, `currency` (always `JPY`) |
| **Reward points** | `goldPoints`, `goldPointRatePercent`, `goldPointValue`: kept as their own fields, never folded into the price |
| **Availability** | `availability`, `inStock`, `isDiscontinued`, `storeStockCount`, `storePickupMessage`, `deliveryMessage`, `deliveryBadge`, `deliveryDate`, `deliveryType` |
| **Media** | `thumbnail`, `images`, `mediaGallery` (feature images with their captions), `videos` |
| **Variants** | `variants[]` with per-variant `price`, `listPrice`, `goldPoints`, `availability`, `storeStockCount`, `deliveryDate` and `image`; plus `variantSkus`, `variantCount` |
| **Details** | `description`, `specifications[]` (`{name, values[]}`), `specificationsFlat`, `categoryRankings` |
| **Reviews** | `rating`, `reviewCount`, `ratingBreakdown` (5/4/3/2/1 star counts), `familyReviewCount`, `unratedReviewCount`, `questionCount`, `customerPhotoCount`, and `reviews[]` with `author`, `rating`, `postedAt`, `body`, `helpfulYesCount`, `helpfulVoteCount`, `purchaseNote`, `decisiveFactors`, `images` |
| **Change tracking** | `changeType`, `changedFields`, `firstSeenAt`, `lastSeenAt` (incremental mode only) |

***

### Modes

#### Search

Give one or more keywords (Japanese or English both work) and, optionally, the store's own filters:

| Input | What it does |
|---|---|
| `queries` | Keywords, each walked as its own search |
| `categoryPath` | Restrict to one category branch, e.g. `19055/19063/206005` or a pasted category URL |
| `makerId` | Restrict to one brand, e.g. `0000001851` or a pasted brand URL |
| `minPrice` / `maxPrice` | Price range in yen |
| `sortBy` | Store default, popularity, newest arrivals, price low to high, price high to low, release date |
| `includeDiscontinued` | Off by default (matching the store), on to also return products it no longer sells |

All of these are sent to Yodobashi itself, so they narrow the result set at the source rather than
being filtered afterwards.

#### URL

Paste Yodobashi links of any of these shapes:

- `https://www.yodobashi.com/product/<id>/`: returns that one product.
- `https://www.yodobashi.com/?word=...`: returns the products in that keyword search.
- `https://www.yodobashi.com/category/19055/19063/`: returns the products in that category branch.
- `https://www.yodobashi.com/maker/0000001851/`: returns that brand's products.

The search filters above are ignored in URL mode, because the URL you paste already carries its own.

***

### Detail and review enrichment

Both are off by default, because both cost more per product.

- **`fetchDetails`** adds the full description, the complete specification table, the whole image
  gallery with captions, the list price and discount, the store's category rankings, and the
  per-variant price, points and stock.
- **`fetchReviews`** adds the star breakdown and the individual reviews.

Each product that gets either kind of enrichment counts as **one** `Detail enrichment` charge, no
matter how much extra data it carried back. A product that is scanned but suppressed by incremental
mode is never charged, even if its detail page was already fetched.

***

### Japan-only scope, confirmed

Yodobashi Camera operates a **single, Japan-only storefront**. This was checked against the live
site rather than assumed, on 2026-08-27:

- There is one storefront domain, `www.yodobashi.com`. No other-country domain, subdomain or
  path-prefixed locale was found.
- The pages carry **no `hreflang` alternates** and **no language or country switcher** anywhere in
  the header, footer or product pages.
- Every price is stated in yen and the product markup declares `priceCurrency: JPY` with no
  alternative currency anywhere.
- Delivery, in-store pickup and reward points are all expressed against Japanese stores and
  Japanese addresses.

So this actor has **no `country` input**, deliberately: an unused country selector would be a
misleading control, not a feature. If Yodobashi ever opens an international storefront, that is a
scoping change, not a hidden default.

### Reviews are available, and are extracted

Yodobashi runs its own review community rather than a third-party review platform, and reviews are
plentiful on representative electronics and appliance items. Verified live on 2026-08-27: a storage
accessory returned a 4.37 average with a full star breakdown (715 / 459 / 112 / 19 / 23) over 1,378
reviews, and a mirrorless camera kit returned 21 / 6 / 2 / 0 / 0 over 29, both with per-review
author, star rating, posted timestamp, body text, helpful votes and the reviewer's stated purchase
reason.

Two honest limits, worth knowing before you plan a run:

- **Twenty reviews per product.** Yodobashi renders its 20 most recent reviews into the page and
  loads any further batches through a control that requires a signed-in shopper session. So
  `reviews[]` holds up to 20 rows, `reviewsReturned` says how many you actually got, and the
  product's real total is always reported alongside it.
- **The review page covers a product's whole variation family.** A colour or capacity sibling
  shares one review wall on Yodobashi. `reviewCount` stays scoped to the exact SKU you asked for,
  `familyReviewCount` and `ratingBreakdown` describe the family, and every review row carries its
  own `productSku` so you can narrow it yourself.

A product with no reviews returns `reviews: []`, `reviewsReturned: 0` and a null `ratingBreakdown`.

***

### Recurring runs: resume and incremental mode

Two different things, in one input section:

- **`resumeFromRunId`** continues ONE interrupted run. Paste a previous run or dataset id and the
  products already collected there are skipped.
- **`incrementalMode`** is for running the same search again and again (for example daily). The
  actor remembers the previous run itself, keyed on the search and its filters, and marks each
  product `NEW`, `UPDATED`, `REAPPEARED`, `UNCHANGED` or `EXPIRED`. Unchanged products are
  suppressed unless you ask for them, so a daily run bills only for what actually moved.

`emitUnchanged` and `emitExpired` are off by default because both return, and bill, extra rows.
`EXPIRED` is only ever produced after a run has provably covered the whole tracked search: never
when a cap stopped it early, never when resume was used, never when part of the search could not be
read, and never when the run returned nothing at all.

#### What counts as a change, and what does not

Some things on this storefront change every single day regardless of the product, and treating them
as changes would mark your entire catalogue `UPDATED` on every run and bill you for it. These are
deliberately excluded from change detection:

- the rolling promised-delivery date (`deliveryMessage`, `deliveryDate`, `deliveryBadge`,
  `deliveryType`), which re-dates itself daily;
- the store's own daily best-seller position (`categoryRankings`);
- the promoted-placement flag (`sponsored`);
- this actor's own `scrapedAt` timestamp;
- the per-review engagement counters (helpful votes, likes, comments) inside `reviews[]`, which tick
  independently of the review text. A genuinely **new** review is still detected as a change.

Everything you would actually monitor stays in: price, list price, discount, reward points,
availability, in-store stock count, rating, review count, specifications, images and variants.

***

### Notes on the returned rows

- **Promoted tiles are excluded from the dataset.** Search and category pages render more tiles than
  they say they returned; the extras are advertising slots. Returning them would make your row count
  disagree with the store's own result count and bill you for adverts, so no advertising tile is
  ever written to the dataset or charged for. A product that is *also* advertised still comes back
  as a normal result: the advert and the genuine result are separated, never merged, so your rows
  match the store's own "showing 1-48 of N" range exactly. In incremental mode an advertised product
  is treated as still on the store, so it is never falsely marked `EXPIRED`.
- **Some catalogue entries genuinely have no price.** In-store-only and no-longer-stocked items are
  published by Yodobashi without a price; `price` is `null` for those and `availability` carries the
  store's own wording. Sorting by price ascending surfaces them first, which is the store's own
  ordering, not a bug.

***

### Limits and cost controls

| Input | Default | Meaning |
|---|---|---|
| `maxItems` | `50` | Total products returned across every keyword and URL. `0` = unlimited. |
| `maxPages` | unlimited | Result pages read per keyword or URL. The store shows up to 48 products per page. |
| `maxReviewsPerProduct` | `20` | Review rows attached to each product. |
| `maxNotifyListings` | `50` | Products written to each MCP connector. Does not affect the dataset. |

Runs are cheap and fast: a five product search finishes in seconds, and the default Apify Proxy
setting is all this store needs, on any plan.

***

### Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol (MCP)
connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the
`mcpConnectors` field, under **🔌 Export to your apps**. Each connector receives a
condensed, human-readable summary per product, not the full JSON, while the complete record always
stays in the Apify dataset. For Notion, set `notionParentPageUrl` to the page the product pages
should be created under, and use `maxNotifyListings` to cap how many products are exported per
connector per run. Supported connectors: Notion, Linear, Airtable and Apify. Leave the field empty
to skip; it never changes the dataset output.

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mcpConnectors` | array | (empty) | Authorized MCP connectors to send results to. Leave empty to skip. |
| `notionParentPageUrl` | string | (empty) | Notion connector only. URL or id of the Notion page under which product pages are created. Ignored by other connectors. |
| `maxNotifyListings` | integer | 50 | Cap on products written to each connector per run. Does not affect the dataset. |

***

### Failure behaviour

The actor would rather fail honestly than return a misleading empty dataset:

- a run that returned nothing **because the store's answers could not be read** fails with a message saying so,
  instead of looking identical to a search with no matches;
- a genuinely empty search finishes successfully with a `ZERO_RESULTS` status message;
- a run with no keywords or URLs finishes with a `NO_INPUT` status message;
- if per-product enrichment starts failing systemically, it is switched off for the rest of the run
  and the base product data keeps flowing, uncharged, instead of the run grinding.

# Actor input Schema

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

How to find products. 'search' runs keyword searches with the store's own filters; 'url' takes Yodobashi product, category, brand or search URLs exactly as you paste them.

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

Keywords to search for (Search mode only). Japanese and English both work. Each keyword runs its own paginated search and the results are combined. Leave empty if you only want to browse a category or a brand.

## `categoryPath` (type: `string`):

Restrict the search to one category branch (Search mode only). Paste a Yodobashi category URL or just its id path, for example 19055/19063/206005 from https://www.yodobashi.com/category/19055/19063/206005/. Leave empty to search the whole store.

## `makerId` (type: `string`):

Restrict the search to one brand (Search mode only). Use the 10-digit maker id from a Yodobashi brand link, for example 0000001851 from https://www.yodobashi.com/maker/0000001851/. Leave empty for all brands.

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

Lowest price to include, in Japanese yen (Search mode only). Leave empty for no minimum.

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

Highest price to include, in Japanese yen (Search mode only). Leave empty for no maximum.

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

Result ordering as offered by the store (Search mode only). Leave on the store default to keep Yodobashi's own popularity ranking.

## `includeDiscontinued` (type: `boolean`):

Off by default, matching the store's own default of hiding products it no longer sells. Turn on to also return discontinued items, which widens the result set considerably.

## `urls` (type: `array`):

Paste Yodobashi URLs (URL mode only). A product page (/product/<id>/) returns that one product; a category, brand or keyword-search URL returns the products it lists, up to your limits below. The filters above are ignored here because your URL already carries its own.

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

Cap on the number of products returned across all keywords and URLs combined. Set 0 for unlimited, bounded only by Max pages and by how many products the store actually has.

## `maxPages` (type: `integer`):

Optional bound on the number of result pages read per keyword or URL. Yodobashi shows up to 48 products per page. Leave empty or 0 for no page limit.

## `fetchDetails` (type: `boolean`):

Adds the full description, the complete specification table, the whole image gallery with captions, list price and discount, category rankings, and per-variant price, points and stock. Slower, and each enriched product adds one enrichment charge.

## `fetchReviews` (type: `boolean`):

Also returns the product's customer reviews: star rating breakdown, and per-review author, star rating, posted date, review text, helpful votes and stated purchase reason. A product with no reviews returns an empty list. Counts towards the same per-product enrichment charge.

## `maxReviewsPerProduct` (type: `integer`):

Cap on review rows attached to each product. Yodobashi server-renders its 20 most recent reviews per product page, so 20 is the practical ceiling; the product's full review count is always reported separately.

## `resumeFromRunId` (type: `string`):

Optional: paste a previous run ID (or dataset ID) from this actor. Products already collected there are skipped, so this run returns only the new ones. Leave empty for a normal run. For recurring monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for recurring monitoring of the same search or URLs. The first run returns everything as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. State is kept separately per search and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from run ID above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key from the search and filter settings, so different searches never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, so never when Max products or Max pages capped it, when Resume was used, or when a page could not be read. This returns, and bills, extra synthetic rows.

## `proxy` (type: `object`):

Leave the default Apify Proxy setting on. It works on every plan, and a country pin is optional and not required for this store.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it here. The connector receives a condensed, human-readable summary per product, not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which product pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on products written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "カメラ"
  ],
  "sortBy": "",
  "includeDiscontinued": false,
  "urls": [
    "https://www.yodobashi.com/product/100000001000045035/"
  ],
  "maxItems": 50,
  "fetchDetails": false,
  "fetchReviews": false,
  "maxReviewsPerProduct": 20,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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",
    "queries": [
        "カメラ"
    ],
    "urls": [
        "https://www.yodobashi.com/product/100000001000045035/"
    ],
    "maxItems": 50,
    "maxPages": 0,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/yodobashi-com-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",
    "queries": ["カメラ"],
    "urls": ["https://www.yodobashi.com/product/100000001000045035/"],
    "maxItems": 50,
    "maxPages": 0,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/yodobashi-com-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 '{
  "mode": "search",
  "queries": [
    "カメラ"
  ],
  "urls": [
    "https://www.yodobashi.com/product/100000001000045035/"
  ],
  "maxItems": 50,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/yodobashi-com-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/yodobashi-com-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/Qa8DRyBWFqbhHhEE5/builds/Y5mIjgPJSmr0s0eGJ/openapi.json
