Zigbang Scraper - Korea Property Listings, Rent & Agents
Pricing
from $1.20 / 1,000 listing records
Zigbang Scraper - Korea Property Listings, Rent & Agents
Scrape Zigbang property listings across Seoul and South Korea, including one-room, villa and officetel rentals and sales. Extract deposits, monthly rent, prices, floor plans, property details, subway access, locations and agent contacts.
Pricing
from $1.20 / 1,000 listing records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
17 days ago
Last modified
Categories
Share
Zigbang Scraper: Oneroom, Villa and Officetel Listings with Deposits, Rent and Agent Contacts
Zigbang Scraper turns Zigbang, one of South Korea's largest home rental marketplaces, into structured listing data. Search by a subway station, neighbourhood or district, or paste listing links or bare ids directly, and pull oneroom (원룸), villa (빌라) and officetel (오피스텔) listings with deposits, monthly rent, size, floor, address and coordinates. Turn on detail enrichment for the full description, appliances and furniture, elevator, bathroom count, direction, parking, move in date, nearby subway lines and the listing's public agent contact block. Schedule the same search to get only new and changed listings, then export to JSON, CSV or Excel, or read the results straight through the API.
Why This Scraper?
- Two ways in. Resolve a Korean location keyword (a subway station, neighbourhood or district) and read every listing around it, or paste listing URLs or bare numeric ids and read exactly those.
- Three listing verticals. Oneroom, villa and officetel, each with server side deal type, deposit, rent, maintenance fee and size filters, so a filtered run reads only the matching slice.
- Detail enrichment on demand. Switch on a per listing pass for the full description, options, elevator, bathroom count, direction, parking, move in date, nearby subway lines and the agent's public office contact block, and pay the surcharge only for listings you actually get back.
- Resume picks up where you left off. Continue an interrupted pull without paying again for records a previous run already collected.
- Incremental mode for recurring searches. Schedule the same search again and again and get every listing classified NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against your own stored baseline.
- A refused run fails loudly. If nothing could be read at all, the run stops with a clear message instead of quietly returning an empty dataset, so "no listings matched" is never confused with "the connection failed."
- Stable, flat records. Every listing ships as one flat row with a consistent field contract, ready for JSON, CSV or Excel export, or the API.
Use Cases
- Renters and relocation services: compare oneroom, villa and officetel options around a subway line before booking viewings.
- Brokerage and property management tools: refresh a district's market snapshot on a schedule and act only on the listings that actually changed.
- Market research and pricing analysts: track deposit and monthly rent ranges by neighbourhood over time.
- Real estate apps and aggregators: pull structured listing data, including public agent contacts, behind your own API or app.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
itemId | 12345678 |
url | "https://www.zigbang.com/home/oneroom/items/12345678" |
serviceType | "원룸" (oneroom) |
title | "Newly painted one room with a private entrance" |
salesType | "월세" (wolse, deposit plus monthly rent) |
deposit / rent | 1000 / 55 (만원, i.e. 10,000,000 / 550,000 KRW) |
manageCost | "60000" (maintenance fee, in KRW) |
sizeM2 / exclusiveAreaM2 | 21.4 / 18.6 |
floor / buildingFloor | "4층" / "6" |
registeredAt | "2026-08-20T09:15:00+09:00" |
isNew | true |
tags | ["역세권", "반려동물가능"] |
district / neighborhood | "샘플구" / "샘플동" |
thumbnailUrl | "https://ic.zigbang.com/ic/items/12345678/1.jpg" |
description | "Recently renovated one room with a bright south facing window." (with detail enrichment) |
options | ["에어컨", "냉장고", "세탁기"] (with detail enrichment) |
elevator / bathroomCount | true / 1 (with detail enrichment) |
roomDirection / parkingAvailableText | "남향" / "가능" (with detail enrichment) |
moveinDate / viewCount | "즉시입주" / 312 (with detail enrichment) |
subways | [{"name": "샘플역", "lines": "2호선"}] (with detail enrichment) |
agent | office name, phone, address and registry number (with detail enrichment) |
changeType / changedFields | "UPDATED" / ["rent"] (incremental mode only) |
firstSeenAt / lastSeenAt | ISO timestamps (incremental mode only) |
The agent object carries the listing's public business contact block exactly as the source publishes it on the listing page: an office name, a name, an office phone, an office address and a registry number. It, along with description, options, elevator, bathroomCount, roomDirection, parkingAvailableText, moveinDate, viewCount and subways, ships only when detail enrichment (fetchDetails) is on. changeType, changedFields, firstSeenAt and lastSeenAt ship only when incremental mode is on; without it, records look exactly like the rows above minus those four fields.
How to Use
- Pick a mode:
search(resolve a location keyword) orurl(paste listing links or bare ids). - In search mode, choose the listing type and narrow with deal type, deposit, rent, maintenance fee and size filters. URL mode ignores these; each pasted listing is read as it is.
- Turn on Fetch listing details if you need the description, options and agent contact block, and set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search around a subway station:
{"mode": "search","query": "강남역","serviceType": "oneroom","subwayRadiusKm": 2,"maxItems": 50}
Narrow with deal type and price bounds (bounds are in 만원 units, i.e. 10,000 KRW):
{"mode": "search","query": "홍대입구","serviceType": "villa","salesTypes": ["wolse"],"depositMax": 2000,"rentMax": 100,"maxItems": 50}
Search with detail enrichment on:
{"mode": "search","query": "마포구","serviceType": "officetel","fetchDetails": true,"maxItems": 30}
Paste listing URLs or bare ids (url mode):
{"mode": "url","urls": ["https://www.zigbang.com/home/oneroom/items/12345678", "12345679"]}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/zigbang-property-scraper").call(run_input={"mode": "search", "query": "강남역", "serviceType": "oneroom", "maxItems": 20})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["title"], listing["deposit"], listing["rent"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/zigbang-property-scraper').call({mode: 'search', query: '강남역', serviceType: 'oneroom', maxItems: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How search scope and Max items interact
One search reads one location scope: a subway radius, or a single geohash cell (a 4 character cell is roughly 39 by 20 km). A dense central area can resolve to thousands of pins in that one scope, so listing cards are then read in batches of up to 15 and the run stops as soon as Max items pushed records is reached. Raise Max items, or set it to 0 for no limit, to read the whole scope. To cover a whole city, run separate searches per district rather than one very wide scope.
Resume and recurring updates, two different mechanisms
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips pushing every listing id already collected there, whether that run used search or url mode. It still reads through the same search scope again, so a repeated search is read in full, but only the not yet seen listings count against Max items and get billed. - Incremental mode (
incrementalMode) is for scheduling the same search again and again. Each listing is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED. A run cannot use both mechanisms at once; setting both fails the run before any request is made. EXPIREDrows are only produced by a scan that read every part of its scope: not resumed, not stopped early by Max items, and it saw at least one listing. That same complete scan always updates the stored baseline to mark absent listings gone, whether or notemitExpiredis on; the flag only controls whether theEXPIREDrow itself is returned and billed that run.REAPPEAREDfollows from that stored state: a listing a later run sees again after an earlier complete scan marked it gone comes back asREAPPEARED, even ifemitExpiredwas off on that earlier run.stateKeynames or shares the stored baseline; leave it empty to key the baseline on the search itself. With incremental mode off, output looks exactly like a plain search or url run.
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).
- Paste the connector's id (or ids) into the mcpConnectors input field.
- For Notion, also set
notionParentPageUrlto the page where items should be created. - Max items sent to a connector (
maxNotifyListings) caps how many of this run's records the export sends, independently ofmaxItems.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third party credentials. Export is best effort: a failing connector never affects the scraped data. Leave mcpConnectors empty to skip it.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search resolves a location keyword; url reads exactly the listings you paste. |
query | string | 강남역 | Location keyword: a subway station, neighbourhood or district name (search mode). |
serviceType | string | oneroom | Listing type: oneroom (원룸), villa (빌라) or officetel (오피스텔). |
subwayRadiusKm | integer | 2 | Radius in km read around a resolved subway station, from 1 to 10. |
geohash | string | (none) | Read this geohash cell directly instead of resolving the keyword (advanced). |
urls | array | (prefill sample only) | Listing URLs or bare numeric ids to read directly (url mode). |
salesTypes | array | (none) | Narrow by deal type: jeonse, wolse, maede or dongi. Leave empty for all types available on the chosen listing type. |
depositMin | integer | (none) | Lowest deposit to include, in 만원 (10,000 KRW) units. |
depositMax | integer | (none) | Highest deposit to include, in 만원 units. |
rentMin | integer | (none) | Lowest monthly rent to include, in 만원 units. |
rentMax | integer | (none) | Highest monthly rent to include, in 만원 units. |
manageCostMin | integer | (none) | Lowest building maintenance fee to include, in 만원 units. |
manageCostMax | integer | (none) | Highest building maintenance fee to include, in 만원 units. |
sizeMin | number | (none) | Smallest floor size to include, in square meters. |
sizeMax | number | (none) | Largest floor size to include, in square meters. |
fetchDetails | boolean | false | Fetch each listing's detail page and bill the detail enrichment surcharge for it. |
maxItems | integer | 20 | Stop after this many listing records. 0 means no limit. |
resumeFromRunId | string | (none) | Continue one interrupted run without paying again for records already collected there. |
incrementalMode | boolean | false | Classify listings NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against a stored baseline of the same search. |
stateKey | string | (none) | Name the incremental baseline yourself; otherwise it is keyed on the search scope. |
emitUnchanged | boolean | false | With incremental mode on, also return (and bill) UNCHANGED rows. |
emitExpired | boolean | false | With incremental mode on, also return (and bill) EXPIRED rows for listings no longer in scope. |
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 records are created. |
maxNotifyListings | integer | 50 | Cap on items sent to a connector export per run. |
proxy | object | {"useApifyProxy": true} | Connection settings. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"itemId": 12345678,"url": "https://www.zigbang.com/home/oneroom/items/12345678","serviceType": "원룸","title": "Newly painted one room with a private entrance","salesType": "월세","deposit": 1000,"rent": 55,"manageCost": "60000","sizeM2": 21.4,"supplyAreaM2": 25.2,"exclusiveAreaM2": 18.6,"roomType": "02","roomTypeTitle": "원룸","floor": "4층","buildingFloor": "6","registeredAt": "2026-08-20T09:15:00+09:00","isNew": true,"status": true,"tags": ["역세권", "반려동물가능"],"badges": [],"address": "서울시 샘플구 샘플동 12-3","city": "서울시","district": "샘플구","neighborhood": "샘플동","lat": 37.55,"lng": 127.0,"thumbnailUrl": "https://ic.zigbang.com/ic/items/12345678/1.jpg","description": "Recently renovated one room with a bright south facing window.","options": ["에어컨", "냉장고", "세탁기"],"elevator": true,"bathroomCount": 1,"roomDirection": "남향","parkingAvailableText": "가능","moveinDate": "즉시입주","viewCount": 312,"imageUrl": "https://ic.zigbang.com/ic/items/12345678/1.jpg","subways": [{ "name": "샘플역", "lines": "2호선" }],"agent": {"name": "김민수","officeName": "샘플공인중개사사무소","officePhone": "02-1234-5678","officeAddress": "서울시 샘플구 샘플로 10","officeRegNumber": "12345-2026-00001"},"changeType": "UPDATED","changedFields": ["rent"],"firstSeenAt": "2026-08-01T02:00:00.000Z","lastSeenAt": "2026-09-20T02:00:00.000Z"}
Plan Requirement
The default connection works out of the box for every route this actor reads, so there is no need to switch to a specialized connection group. If a request is refused, the run automatically retries before giving up on that request.
FAQ
How much does it cost?
You pay per listing record returned, plus the detail enrichment surcharge only for listings whose detail page you actually fetched and that were returned. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Zigbang?
This actor reads only the public listing data Zigbang's own web app serves to every visitor, including agent contact details the source itself publishes on each listing page. Zigbang's robots.txt disallows general crawling outside a small search engine allowlist; this actor is not a search engine crawler, so you are responsible for how you use the data: follow Zigbang's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Unchanged listings are suppressed and not billed unless you also turn on Emit unchanged listings.
Can I use Resume and Incremental mode together?
No. They solve two different problems: Resume continues one specific interrupted run, Incremental mode tracks a recurring search over time. Setting both fails the run immediately with a message asking you to use one, not both.
Why did my run fail instead of returning an empty dataset?
If every request this run made was refused, the run stops with a clear connection problem message instead of returning an empty dataset, so "no listings matched" is never confused with "the connection failed." A search that genuinely matches nothing, or a pasted id the source does not recognize, still succeeds with an empty result.
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 results into Notion, Linear or Airtable.
🔗 Want more electronics data?
Pair this actor with these related scrapers from the same team:
| 🔌 Appliances Online Scraper Scrape appliancesonline.com.au by category, keyword, or URL. Extract title, brand, AUD... | 🏷️ Mudah.my Cars, Property, Jobs & Marketplace Scraper Scrape Mudah.my listings across every category: cars, motorcycles, property, mobiles... |
| 🔌 Darty Scraper Scrape Darty (darty.com) products: current price plus strike-through reference price and... | 🔌 Dienmayxanh Scraper Scrape dienmayxanh.com home appliances and electronics with full specifications, current... |
| 🏷️ Avito.ru Scraper From $1/1K. Scrape structured listings from Avito.ru by region, category, filters, or... | 🔌 Casas Bahia Brazil Electronics & Home Goods Scraper Scrape products from Casas Bahia Brazil by keyword, department, or URL. Filter by brand... |
💬 Support & custom scrapers
- 🐞 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 abotapi@proton.me or message Telegram @abotapi.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.