591.com.tw Scraper | Rentals, Sales, Land & Commercial Listings
Pricing
from $1.00 / 1,000 results
591.com.tw Scraper | Rentals, Sales, Land & Commercial Listings
Extract property listings from 591房屋交易網 591.com.tw, Taiwan’s largest real estate marketplace. Search by city or use 591 URLs. Covers rentals, sales, land, and commercial properties. Returns 50–60 fields, including price, area, GPS coordinates, nearby transit, and agent/owner contact details.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
591.com.tw Taiwan Property Scraper
Collect structured property listings from 591.com.tw, Taiwan's largest property marketplace, across four sections: Rent (租屋), Sale (買屋, resale and new homes), Land (土地), and Commercial (店面, 辦公, 廠房). Search by city and county with price, area, and rental type filters, or paste any 591 list URL. Every record is a clean, flat JSON object with 50 to 60 populated fields, including agent and owner contact details, GPS coordinates, and nearby transit with walking distances.
Why this scraper
- Four sections in one actor: Rent, Sale, Land, and Commercial, each with the section's native fields.
- 50 to 60 fields per listing, more than any comparable 591 actor, including contact name, mobile, phone, LINE and email, plus full GPS, nearby bus and metro stops with distances, lease rules, deposit, fees, and the full high resolution photo gallery.
- Two ways to run: pick a section, regions, and filters, or paste 591 list URLs straight from your browser.
- Forward auto pagination that walks the whole result set by default (no artificial page cap), bounded only by the
maxListingstotal cap so runs stay predictable. - Low cost: runs on the cheapest datacenter connection by default. A residential tier with Taiwan first rotation and a backup pool engages automatically only if datacenter is ever throttled, and a request budget keeps residential spend under control.
- Fast and reliable: lightweight requests, no heavy page rendering, concurrent detail fetching with per record output so partial runs still keep their data.
- Daily/recurring change monitoring: turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED listings on every scheduled run, or resume one specific interrupted walk with
resumeFromRunId.
Data you get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
| id | 21000001 |
| section | rent |
| listingType | rent |
| url | https://rent.591.com.tw/21000001 |
| title | Sample Listing Title |
| price | 18000 |
| priceText | 18,000 |
| priceUnit | 元/月 |
| kindName | 獨立套房 |
| room | 2房 |
| area | 18 |
| floor | 5F |
| regionName | Taipei City |
| sectionName | 中山區 |
| address | 中山區 Sample Road |
| latitude | 25.0000 |
| longitude | 121.5000 |
| communityName | Sample Community |
| deposit | 押金二個月 |
| leaseMinTerm | 最短租期一年 |
| rule | 此房屋男女皆可租住 |
| facilities | ["冰箱","洗衣機","冷氣","網路"] |
| nearbyTransit | [{"type":"subway","name":"Sample Station","distance":300}] |
| tags | ["新上架","可開伙"] |
| photoCount | 12 |
| coverPhoto | https://img1.591.com.tw/house/0000/000000000.jpg |
| photos | ["https://img1.591.com.tw/house/0000/000000001.jpg"] |
| browseCount | 120 |
| postedAt | 此房屋在3天前發佈 |
| contactName | Agent Name |
| contactRole | 仲介 |
| contactMobile | 0900000000 |
| contactPhone | 0200000000 |
| contactEmail | agent@example.com |
| contactLine | sample-line-id |
| isAgent | true |
| scrapedAt | 2026-01-01T00:00:00.000Z |
| changeType | NEW (incremental mode only — see "Resume & recurring updates" below) |
| changedFields | ["price"] (incremental mode, UPDATED rows only) |
| firstSeenAt | 2026-01-01T00:00:00.000Z (incremental mode only) |
| lastSeenAt | 2026-01-02T00:00:00.000Z (incremental mode only) |
Sale, Land, and Commercial records add section specific fields such as unitPrice, mainArea, shape, houseAge, direction, roomCount, hallCount, bathroomCount, and balconyCount where the section publishes them.
How to use
Pick a section, regions, and filters:
{"mode": "search","section": "rent","regions": ["taipei-city", "new-taipei-city"],"minPrice": 10000,"maxPrice": 25000,"fetchDetails": true,"maxPages": 5,"maxListings": 200}
Search resale and new homes for sale:
{"mode": "search","section": "sale","regions": ["taichung-city"],"minArea": 20,"maxPages": 10,"maxListings": 300}
Filter rentals by type (whole home, suite, shared suite, single room, parking):
{"mode": "search","section": "rent","regions": ["kaohsiung-city"],"rentKind": "whole","fetchDetails": true,"maxPages": 3}
Paste 591 list URLs (multi URL supported, filters above are ignored):
{"mode": "url","urls": ["https://rent.591.com.tw/list?region=1&kind=2","https://land.591.com.tw/list?type=2®ion=1&kind=11"],"maxPages": 5,"maxListings": 150}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| mode | string | search | "search" (pick section, regions, filters) or "url" (paste list URLs). |
| section | string | rent | rent, sale, land, or commercial. Search mode only. |
| regions | array | ["taipei-city"] | One or more Taiwan cities or counties. Search mode only. |
| rentKind | string | any | Rental type: whole, suite, shared-suite, single-room, parking. Rent section only. Applies in Search mode and URL mode. |
| minPrice / maxPrice | integer | none | Price bounds. Rent is TWD per month; Sale, Land, Commercial are in 萬 total. Applies in Search mode and URL mode, including a pasted URL. |
| minArea / maxArea | integer | none | Floor area bounds in 坪 (ping). Applies in Search mode and URL mode, including a pasted URL. |
| urls | array | none | 591 list URLs. URL mode only. Pagination starts at the page in the URL and walks forward. |
| fetchDetails | boolean | true | Visit each listing's detail page for the full field set. Turn off for a faster, cheaper list level run. |
| maxListings | integer | 20 | The sole soft cap on the run, applied across the whole run (not per page). 0 means unlimited. |
| maxPages | integer | 0 | Safety bound on result pages walked per region or URL (about 30 listings per page). 0 (default) means unlimited: the walk stops on its own once a page comes back empty or keeps repeating listings already collected, or sooner once maxListings is reached. Set a number only for an explicit page cap below that natural stop. |
| resumeFromRunId | string | none | Continue one specific previous run/dataset: listings already saved there are loaded before scraping starts and skipped, so this run only appends new listings. For recurring daily monitoring of the same search, use incrementalMode instead — see "Resume & recurring updates" below. |
| incrementalMode | boolean | false | Daily/recurring monitoring of this same search. First run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED — unchanged listings are suppressed (not returned, not billed). See "Resume & recurring updates" below. |
| stateKey | string | none | Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your section/regions/URLs/filter settings when left empty. |
| emitExpired | boolean | false | Incremental mode only. Also return listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search (not capped, not a resume). Adds and bills extra synthetic rows. |
| proxy | object | Apify Datacenter | Connection configuration. Datacenter is the low cost default. |
| maxResidentialRequests | integer | 200 | Caps requests on the residential fallback tier. 0 disables residential entirely. |
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 haven't 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.
Output example
Sample shape: values are illustrative placeholders, not from a live listing.
{"id": 21000001,"section": "rent","listingType": "rent","url": "https://rent.591.com.tw/21000001","title": "Sample Listing Title","description": "Full listing description appears here when fetchDetails is on.","price": 18000,"priceUnit": "元/月","deposit": "押金二個月","kindName": "獨立套房","room": "2房","area": 18,"floor": "5F","regionName": "Taipei City","sectionName": "中山區","address": "中山區 Sample Road","latitude": 25.0000,"longitude": 121.5000,"leaseMinTerm": "最短租期一年","rule": "此房屋男女皆可租住","facilities": ["冰箱", "洗衣機", "冷氣", "網路"],"nearbyTransit": [{ "type": "subway", "name": "Sample Station", "distance": 300 }],"photoCount": 12,"coverPhoto": "https://img1.591.com.tw/house/0000/000000000.jpg","contactName": "Agent Name","contactRole": "仲介","contactMobile": "0900000000","contactEmail": "agent@example.com","isAgent": true,"scrapedAt": "2026-01-01T00:00:00.000Z"}
Walking the whole catalogue
By default maxPages is 0 (unlimited): a search or URL entry walks every result page until the storefront naturally runs out — an empty page, or a page that keeps repeating listings already collected — or until maxListings (the run's only soft cap, default 20, set 0 for unlimited) is reached, whichever comes first. Set maxPages to a number only when you want an explicit page cap below that natural stop.
For a very large walk-all pull, use resumeFromRunId in a follow-up run instead of starting over: paste the ID of a previous run (or its dataset) and this run loads the listings it already saved, skips them, and appends only new listings to a fresh dataset. Leave it empty for a normal run.
Resume & recurring updates
Two different needs, two different fields:
| Need | Field |
|---|---|
| A walk-all pull stopped and should continue | resumeFromRunId / automatic checkpoint recovery |
| Run the same search every day/week and receive only what changed | incrementalMode |
| Keep separate recurring campaigns for similar searches | distinct stateKey values |
Resume (resumeFromRunId) continues one specific interrupted or previous large walk: paste a run ID or dataset ID and this run skips listings already collected there, returning only the remaining new ones. An automatic same-run checkpoint also protects against platform migrations/resurrects without any input needed.
Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED listings — unchanged listings are suppressed (not returned, not charged). Turn on emitExpired only when you also want listings that disappeared returned (and billed for) as EXPIRED. State is isolated per section/region/URL/filter combination automatically; set stateKey to name or deliberately share a monitoring campaign.
Example: first run of a monitored search —
{ "mode": "search", "section": "rent", "regions": ["taipei-city"], "incrementalMode": true }
→ every listing comes back with "changeType": "NEW".
Run it again later with the same input —
{ "mode": "search", "section": "rent", "regions": ["taipei-city"], "incrementalMode": true }
→ listings whose price/room/photos/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new listings come back as "changeType": "NEW", listings that vanished and came back are "changeType": "REAPPEARED" — and listings that are still there, unchanged, are not returned at all (suppressed, not charged).
The actor also checkpoints its own progress internally, so if a run is interrupted by a platform migration it picks back up without re-saving (and re-charging for) listings it already wrote.
Plan requirement
This actor runs on any Apify plan, including the free plan, because it defaults to the datacenter connection. For the highest reliability on large runs, a paid plan with residential proxy is recommended; the actor uses it only as an automatic fallback (Taiwan first), capped by the residential request budget, and switches back to datacenter once the connection is healthy again. If a run returns zero results on the free plan, enable residential proxy and try again.