Rakuma Scraper – Rakuten Flea Market Japan (楽天ラクマ) avatar

Rakuma Scraper – Rakuten Flea Market Japan (楽天ラクマ)

Pricing

from $2.00 / 1,000 results

Go to Apify Store
Rakuma Scraper – Rakuten Flea Market Japan (楽天ラクマ)

Rakuma Scraper – Rakuten Flea Market Japan (楽天ラクマ)

Scrape Rakuma (fril.jp, 楽天ラクマ) — Rakuten's flea-market app, Japan's #2 C2C marketplace: fashion, brand bags, sneakers, hobby. Search by keyword, brand, category, price, condition, sold-out; get normalized size, condition rank, seller and images. JP Data Works series.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

JP Data Works

JP Data Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Scrape Rakuma (楽天ラクマ) — Rakuten's flea-market app and Japan's second-largest C2C marketplace after Mercari (tens of millions of listings: fashion, brand bags and shoes, sneakers, cosmetics, hobby, kids) — by keyword, brand and category, with price, condition, sold-out and exclude-word filters, and get clean JSON / CSV with normalized size, condition rank (6–1), category path, seller and images. Optionally open each item page for condition, size, shipping, seller reviews, likes, description and the full gallery. Part of the JP Data Works series of Japanese marketplace scrapers (Mercari, Yahoo! Fleamarket, KOMEHYO, Trefac, Vector Park …) that share one output shape so results can be merged.

Keywords: Rakuma scraper · ラクマ スクレイピング · fril.jp · Rakuten flea market data · Japanese secondhand prices · sold listings price research · KAPITAL, visvim, Comme des Garçons, Supreme, Nike SB used · resale sourcing (eBay, Grailed, Depop, StockX) · price monitoring.

What you get

One row per listing:

  • itemId, itemHash, url, title, brand, brandId
  • priceJpy, status (on_sale / sold), sizeRaw / sizeNorm / size (W32, L, JP3, 26.5cm, FREE)
  • categoryId, categoryPath (メンズ > ジャケット/アウター > Gジャン/デニムジャケット — from the listing card's leaf category), categoryIds, gender
  • sellerId, imageUrl / imageUrls, fetchedAt, keyword, search

With Enrich with item pages each item additionally has conditionRank 6 (新品、未使用) … 1 (全体的に状態が悪い) and conditionLabel, sizeRaw from the item page, shippingPayer (seller 送料込 / buyer 着払い), shippingMethod, shippingDuration, shippingFromArea, anonymousShipping, sellerName, shopName, shopHash, sellerReviews ({ good, neutral, bad }), likes, comments, description and the full-size gallery.

Example item (enriched)

{
"source": "rakuma",
"itemId": "862187021",
"itemHash": "d61f0b0fcd51aaf40a346d015f3af984",
"url": "https://item.fril.jp/d61f0b0fcd51aaf40a346d015f3af984",
"title": "KAPITAL",
"brand": "KAPITAL",
"brandId": "1785",
"priceJpy": 50000,
"status": "on_sale",
"sizeRaw": "L",
"sizeNorm": { "kind": "alpha", "value": "L" },
"size": "L",
"conditionRank": 3,
"conditionLabel": "やや傷や汚れあり",
"categoryId": 542,
"categoryPath": "メンズ > ジャケット/アウター > Gジャン/デニムジャケット",
"categoryIds": [10005, 539, 542],
"gender": "mens",
"sellerId": "17052770",
"sellerName": "rkm0510",
"shopHash": "ddb32042513b176103c3d77a30b5beb2",
"shopName": "rkm0510's shop",
"sellerReviews": { "good": 32, "neutral": 0, "bad": 0 },
"shippingPayer": "seller",
"shippingMethod": "かんたんラクマパック(日本郵便)",
"shippingDuration": "支払い後、4~7日で発送",
"shippingFromArea": "静岡県",
"anonymousShipping": true,
"likes": 1,
"comments": 0,
"description": "ご覧いただきありがとうございます。\n\nストライプ柄フードとダブルブレストが特徴的なインディゴデニム素材のジャケットです。…",
"imageUrl": "https://img.fril.jp/img/862187021/l/2990237096.jpg",
"imageUrls": ["…/l/2990237096.jpg", "…/l/2990237088.jpg", "…/l/2990237184.jpg"],
"fetchedAt": "2026-11-02T03:08:40.000Z",
"detailFetchedAt": "2026-11-02T03:08:47.574Z",
"keyword": "brand:KAPITAL#1785 メンズ>ジャケット/アウター ¥–60000",
"search": { "label": "brand:KAPITAL#1785 メンズ>ジャケット/アウター ¥–60000", "mode": "brand_category", "brandId": "1785", "categoryId": 539, "categoryNames": ["メンズ", "ジャケット/アウター"], "priceMaxJpy": 60000, "status": "on_sale", "clientSideFilters": ["price ¥–60000", "status=on_sale"], "url": "https://fril.jp/brand/1785/category/539" }
}

Without enrichment the detail fields are null and imageUrls holds the listing image, so the dataset always has the same columns.

Output modes — listings or a market summary

outputMode chooses what the dataset contains:

  • items (default) — one row per listing, as above.
  • summary — one market-summary row per search instead of the listings. The Actor still walks the search pages (up to maxItemsPerSearch listings, with enrichDetail if set), but stores only the aggregate — so a run that answers "what does X go for on Rakuma?" costs one summary event per search rather than hundreds of result events.
  • both — the listings plus the summary row.

A summary row (recordType: "summary") has the same shape in every JP Data Works Actor, so you can put several sites side by side:

{
"recordType": "summary",
"source": "rakuma",
"search": { "label": "…", "url": "…", "…": "the resolved search parameters" },
"fetchedAt": "2026-11-02T03:00:00.000Z",
"sampleSize": 180, "totalOnSite": 1243, "scanned": 190, "filteredOut": 10, "withDetail": 0,
"status": { "on_sale": 180, "sold": 0, "unknown": 0 },
"price": { "count": 180, "min": 3300, "p25": 9800, "median": 16500, "mean": 19840, "p75": 25300, "max": 128000, "stddev": 15210 },
"priceOnSale": { "…": "same statistics for on-sale listings" }, "priceSold": { "…": "and for sold ones (sites that list them)" },
"priceHistogram": { "bucketJpy": 10000, "buckets": [ { "fromJpy": 0, "toJpy": 10000, "count": 46 }, "…" ] },
"conditionRank": { "6": 12, "5": 40, "4": 71, "3": 30, "unknown": 27 }, "conditionLabels": { "…": "the site's own labels" },
"sizes": { "M": 48, "L": 41, "W32": 12, "…": 0 }, "sizeKinds": { "alpha": 120, "waist": 30, "numeric": 20, "unknown": 10 },
"brands": { "KAPITAL": 180 }, "categories": { "メンズ > ジャケット/アウター": 95, "…": 0 }, "gender": { "mens": 170, "unknown": 10 },
"listed": { "last24h": 9, "last7d": 41, "last30d": 120 }, "sold": null,
"cheapest": [ { "itemId": "…", "title": "…", "url": "…", "priceJpy": 3300, "conditionRank": 4, "size": "M", "status": "on_sale" }, "…" ],
"cheapestGoodCondition": [ "… cheapest with condition rank ≥ 4 …" ],
"newest": [ "… most recently listed (sites that expose listing times) …" ]
}

Rakuma keeps sold listings in its catalogue, so with status: "all" the summary separates priceOnSale from priceSold — a quick asking-price vs sold-price comparison. The site exposes no listing time, so listed / sold are null.

Input

Two ways to describe what to search, which can be combined in one run:

  • keywords — simple: one search per keyword (KAPITAL, リーバイス 501, Porter タンカー …).
  • searches — structured: objects with any of keyword, brand / brandId, categoryPath / categoryId, priceMinJpy, priceMaxJpy, conditionMin, status, excludeWords, sellerId.

Top-level status, priceMinJpy, priceMaxJpy, conditionMin, excludeWords are defaults for every keyword and search; a value inside a search wins.

FieldTypeDefaultNotes
keywordsstring[]—One search per keyword. Optional when searches is given.
outputModeitems | summary | bothitemsListings, one market-summary row per search, or both (see "Output modes").
searchesobject[]—Structured searches (table below). Each needs a keyword, brand or category.
statuson_sale | sold | allon_salesold = sold-out listings only, with their last price.
priceMinJpy / priceMaxJpyintegernoneClient-side (the site's price filter is robots-disallowed).
conditionMin2–6noneNeeds item pages → turns on enrichDetail.
excludeWordsstring[][]Client-side title filter.
maxItemsPerSearchinteger100Per keyword / search. 40 cards per page, 100 pages max.
maxTotalItemsintegernoneHard cap per run.
dedupeAcrossSearchesbooleantrue
enrichDetailbooleanfalseOne extra request + one detail-page event per item.
maxDetailPagesinteger100Cap on item-page requests per run.
requestDelayMsinteger2000Minimum pause between requests. Please keep ≥ 2000.
proxyConfigurationobjectnoneOptional. Not needed under normal use.
outputFieldsstring[]allKeep only these fields (itemId, url always kept).

Fields of one searches entry (all optional):

FieldExampleHow it is applied
keyword"KAPITAL デニム"Site keyword search (/s?query=), relevance order.
brand"KAPITAL", "COMME des GARCONS"Searched once as a keyword; the brand id is read from the result cards (one extra request per distinct brand). Unknown names are searched as a keyword and filtered by brand name client-side.
brandId1785The site's brand id (fril.jp/brand/<id>). 1785 = KAPITAL.
categoryPath"mens", "ladies", "mens > jackets", "mens > jackets > denim jacket", "メンズ > パンツ > デニム/ジーンズ", "ladies > バッグ"Top category (mens, ladies, kids, cosmetics, hobby, or the Japanese name) optionally followed by > and sub-category names as shown on the site (Japanese, or English for the common ones: tops, jackets, pants, shoes, bags, denim, sneakers, boots, knit, coat, dress, skirt …). The full tree (1,686 categories) is bundled. A name that exists under several parents (e.g. ジャケット/アウター) needs its parent. Unknown paths are used as an extra keyword.
categoryId542The site's category id (fril.jp/category/<id>).
priceMinJpy / priceMaxJpy5000 / 30000Client-side from the card price.
conditionMin4Client-side after the item page: 6 新品、未使用, 5 未使用に近い, 4 目立った傷や汚れなし, 3 やや傷や汚れあり, 2 傷や汚れあり.
status"sold"on_sale (default), sold, all — from the card's SOLD OUT ribbon.
excludeWords["ダメージ"]Client-side: drop items whose title contains any of these.
sellerId"17052770"Client-side: keep only this seller's listings.

How the search is routed (robots.txt forbids combining a keyword with brand_id= / category_id=, so the Actor uses the page types it allows):

InputPage crawledClient-side
keyword only/s?query=<kw>&page=N—
keyword + brand / category/s?query=<kw>&page=Ncards filtered by the brand link / leaf category (and all its sub-categories)
brand only/brand/<id>/page/N—
brand + category/brand/<id>/category/<cid>/page/N—
category only/category/<cid>/page/N—

Examples

Sold KAPITAL jackets — what they actually went for (price research):

{
"searches": [{ "brand": "KAPITAL", "categoryPath": "mens > jackets", "status": "sold" }],
"maxItemsPerSearch": 200
}

Men's denim under ¥20,000 in good condition, with seller and shipping details:

{
"searches": [{ "categoryPath": "mens > pants > denim", "priceMaxJpy": 20000, "conditionMin": 4 }],
"maxItemsPerSearch": 100,
"enrichDetail": true,
"maxDetailPages": 100
}

Keyword within one brand (keyword search filtered by brand client-side):

{ "searches": [{ "keyword": "センチュリーデニム", "brand": "KAPITAL", "status": "all" }], "maxItemsPerSearch": 100 }

Requests are strictly sequential: 100 listings ≈ 3 search pages ≈ 6 seconds; with enrichDetail ≈ 103 requests ≈ 3.5 minutes at the default delay (+1 request when brand names need to be resolved).

Search URL parameters (how the filters map to fril.jp)

Discovered from the site's search form, pager and robots.txt (2026-11-02):

https://fril.jp/s?query=KAPITAL&page=2 https://fril.jp/brand/1785/category/539/page/2 https://fril.jp/category/542/page/2
Actor fieldSite URLNotes
keyword/s?query=relevance order (the sort= parameter is robots-disallowed, so no newest-first)
brandId/brand/<id>brand page; /brand/<id>/category/<cid> for one category
categoryId/category/<id>3-level tree: 10001 レディース, 10005 メンズ, 10003 キッズ/ベビー/マタニティ, 10004 コスメ/美容, 10007 エンタメ/ホビー, 10013 楽器, 10008 チケット …
(pagination)?page=N / /page/N40 cards per page, up to 100 pages
price, condition, status, size—the site's min=, max=, status=, size_id=, sort=, brand_id=, category_id= query parameters are all robots-disallowed; the Actor never sends them and filters client-side instead

Pricing (pay per event)

This Actor uses Apify's pay-per-event model. You only pay for what it produces:

EventCharged whenPrice
Result (apify-default-dataset-item, charged automatically by Apify)one listing is saved to the dataset$0.002
Detail page (detail-page)that listing was enriched from its item page$0.005 (in addition to the result)
Market summary (summary)one summary row is saved (outputMode summary / both)$0.03 per search
Actor start (apify-actor-start)each run starts$0.00005

Example: 100 listings with detail ≈ 100 × $0.002 + 100 × $0.005 = $0.70. Without detail: $0.20. A summary-only run over 3 searches ≈ 3 × $0.03 = $0.09, whatever the number of listings sampled. Set Max total charge on the run to cap spending — the Actor stops cleanly when the limit is reached and you keep everything collected so far.

FAQ

What is Rakuma? Rakuma (楽天ラクマ, formerly Fril) is Rakuten's consumer-to-consumer flea-market app, Japan's second-largest after Mercari, with a strong fashion and brand-goods catalogue and lower seller fees — prices for the same item are often a little below Mercari. Listings are public at fril.jp; sold items stay visible with a SOLD OUT ribbon.

Why is there no "newest first" sort? fril.jp's robots.txt disallows every URL carrying sort= (and the price / condition / size / brand / category query parameters). The Actor only requests the page types the site allows, so results come in the site's default order and all other filters run client-side on the listing cards. For new-arrival monitoring, schedule the Actor and diff itemId against the previous run.

Can I get sold items? Yes — status: "sold" returns sold-out listings with their last price (listings stay in the catalogue after sale), which makes Rakuma a good source for "what did it actually sell for". Sold item pages no longer show the condition and size table, so conditionRank is usually null for them even with enrichment.

Do I need a proxy? No. The site serves the listing and item pages to Apify's datacenter IPs at the default 2-second delay. proxyConfiguration is there if you need it.

How are sizes and conditions normalized? sizeRaw keeps the site text (item page) or the size found in the title; sizeNorm interprets it (waist inches for W32, alpha for S/M/L/LL→XL, numeric for JP sizes such as 3, cm for shoes, free). conditionRank uses 6 = best … 1 = worst — the same scale as our Mercari, Yahoo! Fleamarket, KOMEHYO, Trefac and Vector Park scrapers, so results from several Actors can be merged; conditionLabel keeps Rakuma's own wording.

Is this legal? The Actor collects public listing data only — no login, no purchases, no personal data beyond the public seller name — obeys robots.txt (including the disallowed query parameters) and throttles requests. How you use the data is your responsibility; respect the site's terms of use, keep runs small and scheduled, and do not republish its photos or texts as your own.

How do I call it from code or from an AI agent? Any Apify client works. With the JavaScript client:

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("tokyo-select-jp/rakuma-search-scraper").call({
searches: [{ brand: "KAPITAL", categoryPath: "mens > jackets", status: "sold" }],
maxItemsPerSearch: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

or with plain HTTP (run-sync-get-dataset-items returns the results directly):

POST https://api.apify.com/v2/acts/tokyo-select-jp~rakuma-search-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN
Content-Type: application/json
{ "keywords": ["visvim"], "maxItemsPerSearch": 50 }