Gmarket.co.kr Scraper - Products, Prices & Customer Reviews
Pricing
from $1.00 / 1,000 results
Gmarket.co.kr Scraper - Products, Prices & Customer Reviews
Scrape Gmarket.co.kr product listings and customer reviews into clean JSON. Search by keyword, paste product URLs, or use review-only mode with a product ID. Fast, simple, and built for structured ecommerce data collection.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
9
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Gmarket Global Scraper: Products, Prices and Reviews
Gmarket Global Scraper turns Gmarket Global, the English-language storefront of one of South Korea's largest marketplaces, into a clean JSON dataset. Search by keyword or paste a search-result URL, then flip one toggle to pull customer reviews instead of product cards. Detail enrichment, on by default, adds the seller's legally required business disclosure when it can be read for a product. Export to JSON, CSV or Excel, or read the results straight through the API.
Why This Scraper?
- Two ways to find products. Search by one or more keywords (English or Korean both work), or paste ready-made Gmarket Global search-result URLs with your own filters already baked into the query string.
- One toggle flips the whole output. Turn on "Reviews only" and the actor still uses your keywords or URLs to discover matching products, but pushes one record per customer review instead of one per product.
- Detail enrichment on demand. An optional extra fetch per product adds description text, brand, and the seller's legally required disclosure: company name, manager name, customer-service phone, business registration number, and e-commerce sales registration.
- Clean numeric prices, not just a raw feed. Was price, current price, KRW savings and discount percent are parsed and normalized into numeric fields on every product, alongside a converted currency price.
- Nothing is silently dropped. Every record also carries a
rawfield with the complete original product record from the storefront, next to the parsed fields. - Ad and promotion signals. Filter to the sitewide BigSmile promotion, and read per-product flags for BigSmile enrollment and sponsored (paid) placement.
- Built for schedules. Resume a large walk-all pull across separate runs, or turn on incremental mode so a recurring run returns only new, updated and genuinely reappeared records.
Use Cases
- Price and market research: track KRW and converted prices, discount rates and savings across a catalog of Korean products.
- Cross-border sourcing: filter to items with oversea delivery available, and pull the seller's registered business details before you commit to a supplier.
- Reputation monitoring: pull every review for a set of products, including ratings, delivery scores and seller replies, to watch how a listing is received.
- Marketplace and competitor tracking: schedule the actor with incremental mode to catch new listings, price changes and delisted products without re-scraping everything each time.
- Promotion and ad audits: use the BigSmile and sponsored-placement flags to see which listings are running the sitewide promotion or a paid placement.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
goodsCode | "0000000001" |
title | "Sample Product Title" |
linkUrl | "https://mg.gmarket.co.kr/Item?goodscode=0000000001" |
imageUrl / additionalImages | "https://gdimg.gmarket.co.kr/0000000001/still/280?ver=0" / list of extra image URLs |
currentPriceKrw | 22800 (the price the buyer actually pays, null if the site does not report a sale price) |
wasPriceKrw / savingsAmountKrw | 28500 / 5700 (wasPriceKrw is null when the item is not on a special; savingsAmountKrw is null when the site reports no discount amount) |
discountRatePercent | 20 (null when not on special) |
currencyPrice | "$15.75" |
isOnSpecial | true |
isBigSmilePromo | false (true when the item is enrolled in the sitewide BigSmile promotion) |
isSponsored | false (true for a paid/ad placement) |
isFreeShipping / deliveryInfo | true / "Free" |
sellerCustNo | "000000000" |
miniShopUrl | "https://mg.gmarket.co.kr/samplestore" |
categoryCodeL / categoryCodeM / categoryCodeS | "100000000" / "200000000" / "300000000" |
overseaDeliveryAvailable | true |
translation.english / translation.chinese / translation.japanese | true / true / false |
sellerCompanyName / sellerPhone / sellerBusinessNumber | "Sample Trading Co., Ltd." / "02-0000-0000" / "000-00-00000" (only when detail enrichment is on) |
descriptionText | up to 3,000 characters of cleaned product description (detail enrichment only) |
raw | the complete original product record from the storefront |
scrapedAt | "2026-01-01T00:00:00.000Z" |
When "Reviews only" is on, the actor pushes one record per review instead: productGoodsCode and productLinkUrl link the review back to its product, reviewId is the review's own id, authorNickname (Gmarket-masked) and authorLoginId (unmasked) identify the author, rating (against a ratingMax of 10) and deliveryRating carry the numeric scores, title and comment (plus their English translations, titleEnglish and commentEnglish, when Gmarket provides one) hold the review text, reviewDate and reviewDateText cover timing, hasPhotos and photoUrls cover attached images, variantInfo records the purchased option, sellerReply and sellerReplyDate carry any seller response, isPowerReviewer and readCount are engagement signals, and raw and scrapedAt round out the record the same way product records do.
How to Use
- Pick a mode: keyword search, or paste ready-made Gmarket Global search-result URLs.
- Fill in your keywords or URLs, and set any filters you want: price range, oversea delivery only, BigSmile promotion only.
- Decide whether you want products or reviews ("Reviews only"), and set
maxPagesandmaxListingsto size the run. Leave "Fetch detail pages" on for the full seller disclosure, or turn it off for a faster, leaner pull. - Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Keyword search, default settings:
{"mode": "search","keywords": ["laptop"]}
Keyword search with a price band, oversea delivery only, deeper pagination:
{"mode": "search","keywords": ["headphones", "earbuds"],"minPrice": 10000,"maxPrice": 100000,"overseaDeliveryOnly": true,"maxPages": 3}
Paste a search-result URL with your own filters already in it:
{"mode": "url","urls": ["https://mg.gmarket.co.kr/Search/Search?keyword=phone&minPrice=50000&maxPrice=500000"],"maxPages": 2}
Reviews only, capped total:
{"mode": "search","keywords": ["laptop"],"reviewsOnly": true,"maxReviewsPerProduct": 20,"maxListings": 100}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/gmarket-global-scraper").call(run_input={"mode": "search", "keywords": ["laptop"]})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], item["currentPriceKrw"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/gmarket-global-scraper').call({ mode: 'search', keywords: ['laptop'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
These are two distinct features, and both live under "Resume & recurring updates" in the input:
resumeFromRunIdcontinues ONE interrupted walk-all pull. Paste a previous run or dataset id, and this run loads everygoodsCodeorreviewIdalready saved there and skips them, so it only appends new records.incrementalModeis for scheduling this actor repeatedly against the SAME search. The actor remembers the last run's records itself, keyed by your search scope (mode, keywords or URLs, price range, oversea and BigSmile filters,reviewsOnly,fetchDetails); override withstateKeyto track multiple schedules explicitly. Every pushed record gets achangeTypeofNEW,UPDATED,UNCHANGED,REAPPEAREDorEXPIRED, pluschangedFields,firstSeenAtandlastSeenAt. Every field is compared exceptscrapedAt, the per-requestsellerInfo.EncodedCustNotoken, the review view counter (readCount,raw.ReadCount) and anything you list inignoreFieldsForChanges; those stay in the output. A pasted URL that starts atpageNoabove 1, a capped run or a resumed run is a partial scan and never marks anything EXPIRED.- By default only
NEW,UPDATEDandREAPPEAREDare pushed and billed. Turn onemitUnchangedto also push (and pay for) a full snapshot every run. emitExpired(off by default) pushes a tombstone row for a tracked record that no longer appears, but only after a run that scanned the complete tracked search. A capped, resumed, or partial run never marks anything expired, since it cannot tell "gone" apart from "not reached yet".REAPPEAREDitself can only happen for a record that a previous complete-scan run withemitExpiredon actually marked as gone. Without that history, a listing that comes back is classifiedNEWagain, notREAPPEARED.- The two entity kinds (products and reviews) are tracked in separate namespaces internally, so a product id and a review id never collide, and a new review never makes its parent product look
UPDATED.
- By default only
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify β Settings β Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | "search" | "search" uses keywords plus filters; "url" uses pasted search-result URLs. |
keywords | array | none (prefill: ["laptop"]) | One or more product keywords, English or Korean both work. Search mode only. |
minPrice | integer | 0 | Minimum sale price in KRW. 0 = no minimum. |
maxPrice | integer | 0 | Maximum sale price in KRW. 0 = no maximum. |
overseaDeliveryOnly | boolean | false | Restrict to items that ship outside Korea. |
bigSmileOnly | boolean | false | Restrict to items in the sitewide BigSmile promotion. |
sortBy | string | GLOBAL_RANKPOINT | Result order: GLOBAL_RANKPOINT (relevance), GLOBAL_SELL_QTY (Gmarket ranking order; the storefront has no best-selling order, so this is the same family as relevance), GLOBAL_LOW_PRICE, GLOBAL_HIGH_PRICE, GLOBAL_RECENT (new arrivals). Applies to keyword and pasted-URL runs; a sortType in a pasted URL wins. Low-to-high lists zero-priced ("Free") cards first. |
urls | array | one example URL per supported shape (see the URL shapes table) | Gmarket Global URLs. In URL mode the price, oversea and BigSmile inputs above also apply, but any of them set in the URL itself wins for that URL. The actor reads keyword, category, price range and promotion flags straight from each URL's own query string. URL mode only. Behaviour change: in URL mode with this field left untouched, the example URLs run (capped by maxListings) instead of nothing. |
reviewsOnly | boolean | false | Push one record per review instead of one per product. Still uses the same search or URL flow to discover products first. |
maxReviewsPerProduct | integer | 20 | Reviews-only mode: stop after this many reviews per product. Set 0 to walk every review the product has. |
maxPages | integer | 0 | Pages to walk per keyword or URL (up to 60 products per page). 0 = unlimited, walk all pages until the site runs out of results. |
maxListings | integer | 20 | Cap on total records output (products or reviews, depending on reviewsOnly). Set 0 to walk the entire catalogue. |
fetchDetails | boolean | true | Fetch each product's detail page to add description, brand and the full seller disclosure. Turn off for a faster, leaner scrape. |
resumeFromRunId | string | none | Paste a previous run or dataset id to continue a large walk-all pull; already-saved records are skipped. |
incrementalMode | boolean | false | Recurring monitoring of the same search. See "Resume and recurring updates" above. |
stateKey | string | none | Incremental mode only. Override the auto-derived search-scope key. |
emitUnchanged | boolean | false | Incremental mode only. Also push (and bill) UNCHANGED records every run. |
emitExpired | boolean | false | Incremental mode only. Also push (and bill) a tombstone row for records that disappeared, after a complete scan. |
expireAfterMissedScans | integer | 1 | Incremental mode only. Mark a record EXPIRED only after it was missing from this many consecutive complete scans. EXPIRED means it stopped appearing in the search, which cannot tell a ranking drop from a delisting. |
changeScope | string | all | Incremental mode only. priceAndStock compares only price fields (current, was, sell, original, sale price, savings, discount, on-special flag); nothing else can create an UPDATED row. The search card has no stock field. |
compactUpdates | boolean | false | Incremental mode only. UPDATED product rows carry only ids, link, current price and priceChanges (old and new values). Seller and description data are not in a compact row, so the detail-enrichment charge is not made for it. |
ignoreFieldsForChanges | array | none | Ignore fields when detecting changes (incremental mode only). Dotted paths such as raw.ImageURL or sellerInfo.CompanyName that never count as a change and never appear in changedFields; they stay in the output. |
proxy | object | none (prefill: Apify Proxy switched on) | Network connection settings. If this field is left out entirely, requests go out with no proxy configured at all. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which item records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
query | string | none | Alias of keywords for saved inputs written for other Gmarket scrapers. |
startUrls | array | none | Alias of urls. |
maxItems | integer | none | Alias of maxListings. |
proxyConfiguration | object | none | Alias of proxy. |
URL shapes (URL mode)
| Shape | Example | What you get |
|---|---|---|
| Search | https://mg.gmarket.co.kr/Search/Search?keyword=laptop | Products for the keyword. |
| Paginated search | https://mg.gmarket.co.kr/Search/Search?keyword=laptop&pageNo=2 | Walks forward from page 2 (partial scope: never marks EXPIRED). |
| Filtered search | https://mg.gmarket.co.kr/Search/Search?keyword=laptop&minPrice=100000&maxPrice=500000&overseaTransYn=Y&isBigSmile=true | Price, oversea and BigSmile filters applied. |
| Seller-scoped search | https://mg.gmarket.co.kr/Search/Search?keyword=laptop&sellCustNo=1 | The storefront ignores sellCustNo; results are the plain keyword results and the log says so. |
| Category listing | https://mg.gmarket.co.kr/Category/List?lcId=100000028 | Products of that category. |
| Category hub | https://mg.gmarket.co.kr/AllCategory | Expanded to the top-level categories (first 100), each walked like a category listing. |
| Product detail | https://mg.gmarket.co.kr/Item?goodscode=4196091684 (also goodsCode=) | That one product, matched on its product code. |
| Review page | https://mg.gmarket.co.kr/Review/Review?GoodsCode=4196091684 | Accepted when pasted, but it resolves to the same product as the Item URL, so it is not one of the shipped examples. |
| Homepage | https://global.gmarket.co.kr/Home/Main | Lists no products: skipped with a warning in the log. |
item., www. and m. hosts are read through the Global storefront with the same parameters (a warning is logged). A product code the storefront no longer returns logs a warning and emits nothing.
Compatibility aliases
Saved inputs written for other Gmarket scrapers run unchanged: query maps to keywords, startUrls to urls (strings or {url} objects), maxItems to maxListings and proxyConfiguration to proxy. The canonical field wins when both are set.
Additional output fields
Every product row also carries snake_case fields: product_id, product_url, price_krw, original_price_krw, coupon_price_krw, discount_amount_krw, price_usd, discount_percent, is_free_shipping, is_sponsored, is_oversea_delivery, is_big_smile, is_adult, seller_id, shop_handle, category_code_l, category_code_m, category_code_s, images_count, images, image_url, scraped_at. They repeat values already in the camelCase fields and are not used for change detection.
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"goodsCode": "0000000001","title": "Sample Product Title","linkUrl": "https://mg.gmarket.co.kr/Item?goodscode=0000000001","imageUrl": "https://gdimg.gmarket.co.kr/0000000001/still/280?ver=0","sellPriceKrw": 22800,"currencyPrice": "$15.75","discountRate": "20","wasPriceKrw": 28500,"currentPriceKrw": 22800,"savingsAmountKrw": 5700,"discountRatePercent": 20,"isOnSpecial": true,"isBigSmilePromo": false,"isSponsored": false,"isFreeShipping": true,"deliveryInfo": "Free","sellerCustNo": "000000000","miniShopUrl": "https://mg.gmarket.co.kr/samplestore","categoryCodeL": "100000000","categoryCodeM": "200000000","categoryCodeS": "300000000","overseaDeliveryAvailable": true,"sellerCompanyName": "Sample Trading Co., Ltd.","sellerManagerName": "John Doe","sellerPhone": "02-0000-0000","sellerBusinessNumber": "000-00-00000","sellerEcommerceNumber": "0000-Seoul-0000","descriptionText": "Sample product description text.","brand": "SampleBrand","translation": { "english": true, "chinese": true, "japanese": false },"raw": {},"scrapedAt": "2026-01-01T00:00:00.000Z"}
Plan Requirement
An Apify plan with proxy access is required: the actor reads the Gmarket Global mobile storefront through your Apify Proxy setting. Measured in testing, the storefront serves its search, category, product-detail and review endpoints from datacenter IPs, so the default Apify Proxy (datacenter) is enough and residential is not required. Other Gmarket hosts (www., m., item.) block datacenter IPs with a bot challenge, which is why pasted URLs on those hosts are rewritten to the Global storefront. Keep the proxy switched on: if you drive the actor through the API with the proxy field omitted, requests go out with no proxy at all.
If no proxy connection can be made (the proxy refuses the connection, or the proxy is switched on but no proxy credentials are available, in which case the actor never falls back to a direct connection), the run fails with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required." If the proxy works but no results page can be loaded, it fails with: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later." Each request has a 25-second budget, and a run that has served at least one page and then loses pages finishes with the partial data it already collected.
Pricing and billing
Billing follows what the code charges, nothing hidden:
- Run start: the platform's start event, once per run.
- Delivered record: one dataset-item event per row pushed to the dataset, whether a product row or a review row. Rows incremental mode suppresses (UNCHANGED, or not requested) are not pushed and not billed.
- Detail enrichment: with
fetchDetailson (the default), onedetail-enrichmentevent per product row where the detail page was actually fetched and parsed. A failed detail fetch, a suppressed row and a compact UPDATED row are never charged it. TurnfetchDetailsoff to skip it. - Reviews: review rows bill as delivered records only; there is no separate review event.
maxReviewsPerProduct(default 20, previously 50;0= every review) andmaxListingsbound the cost of a run.
The Pricing tab shows the current rates.
Output views
The dataset has these views in the Console: Results (all rows), Listings (product cards with price and discount), Reviews (review rows with author, rating and text), Changes (incremental) (change type, changed fields and price changes) and Sellers (seller disclosure: company, phone, business number). A run over several targets also stores a run summary under the key OUTPUT.
FAQ
How much does it cost?
You pay the run-start event, one event per record delivered to the dataset, plus an additional event for each record where detail enrichment (fetchDetails) successfully fetched and parsed seller or description data. A record that incremental mode suppresses as UNCHANGED, or one whose detail fetch fails, is never charged that surcharge. The Pricing tab shows current rates; use maxListings to cap the size, and the cost, of any run. In reviews-only mode each review is one delivered record, and maxReviewsPerProduct (default 20, one page per product; previously 50) caps how many you get per product.
Is it legal to scrape Gmarket Global?
This actor collects only publicly available product listings and customer reviews. You are responsible for how you use the data: follow Gmarket's terms and the laws that apply to you, and get legal advice before any commercial redistribution, especially of the seller's registered business details or review authors' text.
Can I get only new, changed or removed listings on a schedule?
Yes. Schedule the actor and turn on incremental mode. Each run then returns only NEW, UPDATED and REAPPEARED records by default. Turn on emitUnchanged for a full snapshot every run instead, or emitExpired to also get a tombstone row for listings that dropped out, but only once a run has scanned the complete tracked search; a capped, resumed or partial run never marks anything expired. REAPPEARED itself only happens for a listing that a prior complete-scan run with emitExpired on already marked as gone; without that history a returning listing is classified NEW again.
What is the difference between "Resume from a prior run" and "Incremental mode"?
resumeFromRunId continues ONE interrupted walk-all pull: it loads the ids already saved in that specific run's dataset and skips them, so a big pull picks up where it left off. Incremental mode is for scheduling the SAME search repeatedly: it remembers the last run's records itself, keyed by your search scope, and classifies each new run's records against that memory. The two can be combined once, to bootstrap a new incremental baseline from a completed walk-all pull, but the actor refuses the combination if this search already has saved incremental state, so a run never silently starts a second, overlapping baseline.
Why might a run fail instead of just returning an empty dataset?
The run fails outright in four cases: no keywords in search mode, no usable URLs in URL mode, a resumeFromRunId that does not resolve to a readable run or dataset, or Incremental mode combined with resumeFromRunId when that search already has saved incremental state. If nothing at all was scanned, the run finishes successfully with a "No items returned" status message and an empty dataset. If a page fetch fails after retries partway through an otherwise productive run, that search stops early but the run still finishes successfully with whatever partial data it already collected, without a separate status message.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each record into Notion, Linear or Airtable at the end of the run, up to maxNotifyListings records per connector (default 50).
π Want more e-commerce data?
Pair this actor with these related scrapers from the same team:
| π Naver Shopping Scraper Scrape Naver Shopping products by Korean or English keyword, or by URL. Returns 190+... | π Coupang Scraper Scrape Coupang.com products by keyword, category or URL. Extract 20+ fields including... |
| π·οΈ bol.com Scraper Scrape bol.com products: title, price, list price and discount, EAN, brand, images... | π Castorama.fr Scrape Castorama.fr DIY and home-improvement products by keyword, category, or URL... |
| π Zalando Scraper Scrape Zalando products: name, brand, current and original price, discount, sizes... | π Cdiscount Scraper Scrape product data from Cdiscount.com by keyword, category, or URL. Apply filters and... |
π Browse all abotapi scrapers
π¬ Support
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email contact@abotapi.com.
- β Enjoying it? A quick review on the actor page helps other users find it.