Yanolja Scraper at a glance
Yanolja Scraper is a ready-to-run Apify actor from abotapi for collecting web data. Its documented output includes id, stay id, rowtype, url and listing image, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.00 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Web data
- Pricing
- $2.00 per 1,000 results (Free plan), from $1.50 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 24 options
Scrape Yanolja (NOL), Korea's largest accommodations marketplace, by region or URL. Every row carries name, address, coordinates, phone, star class, room types with per-night rates, review score and review text, amenities, policies and photos from one stay page read.
What Yanolja Scraper: Stays, Rates & Reviews can do
- Two ways to scope a run. Browse the site's own ranked lists by Korean region and stay group, or paste stay and collection links directly; both return the same full record shape.
- Full stay detail, not just a listing card. Each enriched record carries room types with per-night rates, review score and highlighted review text, address and coordinates, the stay's own booking phone, facilities, policies and photos, all from one stay page read.
- Availability rates, not stale prices. Overnight and day-use rates come from the site's own next-night availability window, including sold-out flags, so a returned price is what the site is quoting right now.
- Reorder the rows you collected. Sort one run's output by price or review score with a single input field, instead of post-processing it yourself.
- Resume a big crawl without repaying for it. Paste a previous run's id and this run skips every record it already collected there.
- Built for schedules. Incremental mode returns only new, updated and reappeared records on recurring runs, and a refused run fails loudly instead of returning an empty dataset.
Choose what to collect
These inputs let you configure Yanolja Scraper: Stays, Rates & Reviews. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | How to start the scrape. 'search' browses the site's own ranked collection pages for the regions you list. 'url' processes the Yanolja URLs you paste: a stay URL (a page ending in /stay/domestic/) is fetched as a single stay, and a collection URL (a page starting with /programmatic/domestic-accommodation/) is browsed like a search, its own path deciding the scope. |
locationsarray | One or more Korean region or place names, for example '서울', '제주', '부산', '가평'. Each name is matched against the region names of the site's ranked collection pages, and every matching collection is scraped independently. Search mode only: in URL mode the pasted URL decides its own scope. A match with no ranked collection for a typed group is skipped with a warning, never invented. |
categoryGroupstring | Narrow search mode to one availability group the site itself publishes: hotels and resorts, motels, or pensions and poolvillas. Search mode ONLY: in URL mode the pasted URLs decide their own scope. Leave empty for every group the region publishes. |
urlsarray | Paste stay URLs (https://nol.yanolja.com/stay/domestic/1000102592, optionally with ?checkIn=YYYY-MM-DD&checkOut=YYYY-MM-DD, or the m.yanolja.com form), collection URLs (https://nol.yanolja.com/programmatic/domestic-accommodation/) or the two published sitemap indexes (expanded up to Max items). A pasted stay URL returns that single stay in full for its dates; a pasted collection URL is browsed for its list. Leaving this field untouched reads three different stays (plain, dated, m.yanolja.com form), two collection pages and the two sitemap indexes, which expand to as many stays as Max items allows. The price and ordering filters below still narrow what the run keeps. |
minPriceKrwinteger | Only keep rows whose lowest available rate is at least this many Korean won. Applied to the rows this run reads. Applies in BOTH search mode and URL mode. |
maxPriceKrwinteger | Only keep rows whose lowest available rate is at most this many Korean won. Applied to the rows this run reads. Applies in BOTH search mode and URL mode. |
checkInstring | Stay date (YYYY-MM-DD) the stay pages are read for, so room rates and sold-out flags are those of that night. Set together with Check-out date; a pair that is incomplete or not in order is ignored. A date pair already in a pasted stay URL wins. Applies in BOTH search mode and URL mode, only when full stay details are on. |
Show 17 more inputs
| Input | What it controls |
|---|---|
checkOutstring | Departure date (YYYY-MM-DD), after the check-in date. See Check-in date. |
sortResultsBystring | Arranges the rows this run collected, after they are read. This is a local tidy up of one run's output, not a catalogue wide ordering. Applies in BOTH search mode and URL mode. |
fetchDetailsboolean | Read each listing's own stay page for the complete record: room types with per-night rates, review score and review text, address, coordinates, phone, amenities, policies and photos. This IS the main data read, because a bare listing row carries almost none of it, so leave it on unless you only want the cheap name-and-image listing stubs. Turning it on adds the Stay detail enrichment charge per record actually enriched this run. |
maxItemsinteger | The single cap on this run: stop after collecting this many records across all regions, values and URLs. Set 0 for unlimited. |
maxPagesinteger | Safety bound on how many of the site's ranked collection pages to walk per region name. Leave empty (0) for no page limit: the run then stops at Max items, not here. Collection pages are single ranked lists, so in practice one region rarely needs more than a handful of pages. |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for records already collected there. Use this after an interrupted or capped run. For recurring monitoring of the same search, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or weekly recurring monitoring of the same scope, for example a region price watch. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. What is compared: every field of the stay record (rates, sold-out flags, room rates, description, facilities, photos, ratings and review counts); a change to any of them returns UPDATED with changedFields naming it. Always excluded: scrapedAt and detailCarriedForward, plus any field you list in Ignore fields. Rate moves ARE reported as UPDATED: on an accommodation marketplace the rate is the signal, not noise; use What counts as a change to compare only rates and sold-out flags. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately per region, URL and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above. |
stateKeystring | 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 automatically from the regions, URLs and filters, so two different scopes never mix state. |
changeScopestring | All fields (default): any change to the stay record, except the always-ignored bookkeeping fields, returns an UPDATED row. Price and availability only: only the lowest, overnight and day-use rates, the sold-out flags and each room's rates return an UPDATED row; changes to descriptions, photos, facilities, reviews or ratings never do. Changing this option keeps your saved state: stays are compared against what was stored, so it does not return the whole catalogue as NEW. |
emitUnchangedboolean | Off by default. Turn on to also return records 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 specifically want a full snapshot every run. |
emitExpiredboolean | Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked scope: not when Max items capped it, not when Resume was used, and not when the run was refused. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking. |
expireAfterMissedScansinteger | Only used with Emit expired records. A stay is marked EXPIRED only after it has been missing from this many full scans in a row (default 1). Raise it (for example 3) so a stay that briefly drops out of a listing is not reported as gone. A stay that comes back resets the count. A stay missing from the listing is not proof it is unavailable to book: use the sold-out fields for availability. |
compactUpdatesboolean | Off by default. When on, UPDATED rows (and EXPIRED rows) are short: ids, url, name, the current rates and sold-out flags, plus priceChanges and variantChanges showing the old and new value of each moved rate or sold-out flag, per room type. NEW rows always carry the complete stay record. |
ignoreFieldsForChangesarray | Optional. Field names to exclude from UPDATED change detection, in addition to the built-in handling (scrapedAt and detailCarriedForward never trigger an UPDATED). Use this if a field in your setup turns out to be noisy. To ignore a field inside each room while still tracking room rates, use a dotted name such as rooms.photos (also rooms.benefits, rooms.subTitle). Ignoring rooms itself would also hide room rate changes. |
mcpConnectorsarray | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, not the full record; the complete record always stays in the dataset. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL or id of the Notion page under which record pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on records written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
recordIdID (text)stayIdStay ID (text)rowTyperowTypeurlURL (link)listingImageUrlListing image (image)nameStay (text)stayGroupGroup (text)hotelStarStar class (text)addressAddress (text)cityNameCity (text)sellerPhonePhone (text)ratingValueRating (number)Show 24 more fields
reviewCountReviews (number)lowestPriceKrwLowest rate (KRW) (number)overnightPriceKrwOvernight rate (KRW) (number)dayUsePriceKrwDay-use rate (KRW) (number)overnightSoldOutOvernight sold out (text)dayUseSoldOutDay-use sold out (text)priceRangePrice range (text)facilitiesFacilities (array)descriptionDescription (text)gptReviewSummaryReview summary (text)reviewHighlightsReview highlights (array)mainImageUrlMain image (image)photoUrlsPhotos (array)roomsRoom types (array)checkInTimeCheck-in (text)checkOutTimeCheck-out (text)cancelPolicyCancellation policy (text)popularityMessagepopularityMessagechangeTypeChange type (incremental mode) (text)changedFieldsChanged fields (incremental mode) (array)firstSeenAtFirst seen (incremental mode) (date)lastSeenAtLast seen (incremental mode) (date)latitudeLatitude (number)longitudeLongitude (number)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"recordId": "100000001",
"stayId": "100000001",
"rowType": "stay",
"url": "https://nol.yanolja.com/stay/domestic/100000001",
"name": "Sample Stay at Sample District",
"subtitle": "Sample subtitle text",
"stayGroup": "Motel",
"hotelStar": "3",
"badges": [
"Sample badge one"
],
"address": "Sample-si, Sample-gu, Sample-daero 12",
"latitude": 37.11,
"longitude": 127.02,
"cityName": "Sample-si",
"sellerPhone": "0501234xxxx",
"ratingValue": 4.2,
"reviewCount": 456,
"priceRange": "Room 20,000 KRW and up",
"lowestPriceKrw": 36000,
"overnightPriceKrw": 36000,
"dayUsePriceKrw": null,
"overnightSoldOut": false,
"dayUseSoldOut": true,
"checkInTime": "16:00",
"checkOutTime": "12:00",
"facilities": [
"Free parking",
"Sample amenity"
],
"reviewHighlights": [
{
"reviewer": "Sample user*",
"score": 5,
"date": "2025.01.02",
"content": "Clean rooms, quiet at night, would stay again."
}
],
"gptReviewSummary": "Clean rooms, helpful staff",
"cancelPolicy": "Cancel 1 day prior: full refund",
"mainImageUrl": "https://example.com/sample-main.jpg",
"photoUrls": [
"https://example.com/sample-1.jpg",
"https://example.com/sample-2.jpg"
],
"rooms": [
{
"roomTypeId": 250000,
"roomTypeName": "Sample room double",
"subTitle": "Sample walk-in type",
"overnightPriceKrw": 36000,
"dayUsePriceKrw": null,
"benefits": [
"Streaming service included"
]
}
],
"scrapedAt": "2026-09-29T00:00:00Z"
}Ways to use this data
- Travel meta-search and price comparison: track live overnight and day-use rates plus sold-out flags across motels, hotels and pensions in the regions you serve.
- Revenue management and market research: benchmark rate positioning, review scores and amenities against comparable stays in the same region and stay group.
- Travel content and itinerary tools: pull address, coordinates, photos and policy text to build region guides or booking adjacent content.
- Price drop and availability monitoring: schedule the same region with incremental mode and get only the stays whose rate or availability actually changed.
- Review and reputation tracking: collect rating value, review count and the site's own review highlights to watch sentiment over time.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Yanolja Scraper return?
The documented output for Yanolja Scraper includes id, stay id, rowtype, url, listing image, stay, group and star class. Availability of each field depends on the source page and the selected mode.
How much does Yanolja Scraper cost?
It costs $2.00 per 1,000 results on the Apify Free plan and from $1.50 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Which output views does the dataset have?
Overview (the main stay columns), Detail (rooms, rates, policies and review highlights) and Changes (incremental mode: changeType, changedFields, priceChanges, firstSeenAt, lastSeenAt).
Can I get only new or changed stays on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you also turn on Emit unchanged.
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 results into Notion, Linear or Airtable.
