591.com.tw Scraper - Rentals, Sales, Land & Commercial Listings avatar

591.com.tw Scraper - Rentals, Sales, Land & Commercial Listings

Pricing

from $1.00 / 1,000 results

Go to Apify Store
591.com.tw Scraper - Rentals, Sales, Land & Commercial Listings

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

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

45

Total users

17

Monthly active users

14 days ago

Last modified

Security

Limited permissions

Share

591.com.tw Scraper: Rent, Sale, Land and Commercial Listings

591.com.tw Scraper collects 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 and area filters, or paste any 591 list URL straight from your browser. Every record is a flat JSON object with up to 50 to 60 populated fields when detail fetching is on, including agent or owner contact details, GPS coordinates, and nearby transit with walking distances. Turn on Incremental mode for recurring monitoring, export to JSON, CSV or Excel, or pull results through the API.

Why This Scraper?

  • Four sections in one actor. Switch between Rent, Sale, Land, and Commercial, each returning that section's own native fields.
  • Deep records. Up to 50 to 60 populated fields per listing when detail fetching is on, including contact name, mobile, phone, LINE and email, full GPS coordinates, nearby bus and metro stops with distances, lease rules, deposit, fees, and the full photo gallery.
  • Two ways to search. Pick a section, regions, and filters, or paste 591 list URLs you already refined in your browser; pasted URLs keep every filter they carry.
  • Complete pagination by default. A search or URL walks the whole result set until the storefront naturally runs out, bounded only by your Max total listings cap, so you decide the size of a run instead of an artificial page limit.
  • Built for monitoring. Turn on Incremental mode to get only NEW and UPDATED listings on every scheduled run, or resume one specific interrupted walk with resumeFromRunId.
  • Resilient delivery. Records are written one at a time as they're collected, so an interrupted run still keeps everything gathered so far, and the run automatically retries with a different connection when one is refused.
  • All of Taiwan. Every city and county 591 covers, from Taipei City to Kinmen County.

Use Cases

  • Property portals and lead generation: aggregate rent and sale listings with agent or owner contact details to build your own listing feed or lead pipeline.
  • Market research and appraisal: track price, unit price, and area across regions and property types to build comparable-sales datasets.
  • Relocation and rental search tools: filter by region, price, and area to power a rental matching app or alert bot.
  • Land and commercial site scouting: search plots and commercial units by region for feasibility and investment screening.
  • Recurring monitoring: watch a saved search on a schedule and forward only new or changed listings into your own alerting system.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
id99999999
section"rent" (also "sale", "land", "commercial")
listingType"rent" (also "sale")
url"https://rent.591.com.tw/99999999"
title"Sample Listing Title"
price / priceText18000 / "18,000"
priceUnit"元/月"
kindName"整層住家"
room"2房1廳"
area18
floor"5F"
regionName / sectionName"台北市" / "中山區"
address"中山區 Sample Rd"
latitude / longitude25.0600 / 121.5300
communityName"Sample Community"
deposit"押金二個月"
facilities / tags["冰箱","洗衣機","冷氣","網路"] / ["新上架","可開伙"]
nearbyTransit[{"type":"subway","name":"Sample Station","distance":300}]
photoCount / coverPhoto12 / "https://img1.591.com.tw/house/0000/000000000.jpg"
postedAt"此房屋在3天前發佈"
contactName / contactRole"Sample Agent" / "仲介"
contactMobile / contactLine"0900000000" / "sample-line-id"
isAgenttrue
scrapedAt"2026-01-01T00:00:00.000Z"

Sale, Land, and Commercial records add section specific fields where that section publishes them, such as unitPrice, mainArea, shape, houseAge, direction, roomCount, hallCount, bathroomCount, balconyCount, and allFloors. contactPhone, contactEmail, leaseMinTerm, and rule are also part of every record's shape but are commonly empty on Rent listings and populated more often on Sale, Land, and Commercial listings, only when that listing itself publishes them. In Incremental mode, every record above also carries changeType (NEW, UPDATED, REAPPEARED, or EXPIRED; unchanged listings are suppressed and not returned), changedFields on UPDATED rows, and firstSeenAt / lastSeenAt timestamps.

How to Use

  1. Pick a mode: search (choose a section, regions, and filters) or url (paste 591 list URLs).
  2. For Search mode, pick a section (Rent, Sale, Land, Commercial), one or more regions, and any price/area filters.
  3. Turn Visit each listing's detail page on for the full field set, or off for a faster, cheaper, list-level-only run.
  4. Set Max total listings to control run size and cost, then click Start. Download the dataset as JSON, CSV, or Excel, or read it through the API.

Search rentals in Taipei and New Taipei City within a price range:

{
"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 (several at once; the price, area, and rental type filters above still narrow the results of pasted list pages; a pasted single-listing page always returns that one listing):

{
"mode": "url",
"urls": [
"https://rent.591.com.tw/list?region=1&kind=2",
"https://land.591.com.tw/list?type=2&region=1&kind=11"
],
"maxPages": 5,
"maxListings": 150
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/591-com-tw-scraper").call(run_input={
"mode": "search",
"section": "rent",
"regions": ["taipei-city"],
"maxListings": 50,
})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["title"], listing["price"], listing["priceUnit"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/591-com-tw-scraper').call({
mode: 'search',
section: 'rent',
regions: ['taipei-city'],
maxListings: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets, or webhooks from the Integrations tab.

URL mode

Set mode to url and paste any of these 591 address shapes. Each is handled the same way every time:

ShapeExampleResult
Rent listhttps://rent.591.com.tw/list?region=1Walks the list; region, kind, price, sort and page parameters in the URL are applied.
Rent list, later pagehttps://rent.591.com.tw/list?region=1&page=2Starts at page 2 and walks forward.
Rent list, filtered and sortedhttps://rent.591.com.tw/list?region=3&kind=2&price=10000_20000&order=posttime&orderType=descThe filters and sort order in the address are kept.
Rent site roothttps://rent.591.com.tw/Treated as the Taipei City rent list. Offered as a prefill example only, not in the shipped default, because it returns the same rows as the first rent list.
Rent listinghttps://rent.591.com.tw/22206852One row for that listing.
Sale listhttps://sale.591.com.tw/?shType=list&regionid=1Walks the sale list.
Sale list endpointhttps://bff-house.591.com.tw/v1/web/sale/list?type=2&category=1&regionid=1&firstRow=0&shType=listWalks the sale list from the given offset.
Land listhttps://land.591.com.tw/list?type=2&region=1&kind=11Walks the land list.
Land listinghttps://land.591.com.tw/sale/21103521One row for that listing.
Commercial listhttps://business.591.com.tw/list?type=1&region=1Walks the commercial list.
Commercial listinghttps://business.591.com.tw/rent/21777031One row for that listing.
New-build projecthttps://newhouse.591.com.tw/137287One row for that project (section is newhouse).

In URL mode the rental type, price and area filters and Sort by (rent lists) still apply to pasted list pages; a pasted single-listing page always returns that one listing; Rooms and Keyword are Search-mode only.

Addresses of any other shape, such as the mobile host or the old business search form, are skipped with a warning in the run log, never silently turned into an empty result.

Behaviour change: the urls field now ships with one example per distinct shape above as its default (the rent site root is left out because it resolves to the first rent list). Running URL mode with the field left untouched scrapes those examples (capped by Max listings); clear the field and paste your own addresses to scrape only those. The alias startUrls is also accepted: when it is given and urls is still the untouched example default, only your startUrls are scraped. A single listing page always loads its own detail page, so it returns a full row even when Fetch details is off.

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, either an empty page or a page that keeps repeating listings already collected, or until maxListings (the cap on the whole run, default 20, set 0 for unlimited, split evenly across the regions or URLs you list) 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.

Resume and recurring updates

Two different needs use two different fields. 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 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 and UPDATED listings; unchanged listings are suppressed, not returned, and not charged. Turn on emitExpired to also learn when a tracked listing disappears; once a run with emitExpired on has completed a full, uncapped scan, a listing that comes back afterward is returned as REAPPEARED, and one that stays gone is returned as EXPIRED and billed for. Change detection compares every output field, including nested values. Left out of the comparison but kept in the output: scrapedAt, sourceUrl, pageIndex, the view counters (browseCount, browsePc, browseMobile), the site's own updatedAt and refreshedAt, and the rotating photo-server number in photo URLs; add your own with ignoreFieldsForChanges. EXPIRED detection only runs after a complete scan: a Max listings or Max pages cut, a pasted URL starting at ?page=2 or later, or a resumed run never marks anything EXPIRED. State is isolated per section, region, URL, and filter combination automatically; set stateKey to name or deliberately share a monitoring campaign.

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.

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.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to 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

ParameterTypeDefaultDescription
modestring"search"Two ways to drive the scraper: search (pick section, regions, and filters) or url (paste 591 list URLs).
sectionstring"rent"Which 591 marketplace to scrape: rent, sale, land, or commercial. Search mode only; a pasted URL carries its own section.
regionsarrayprefill ["taipei-city"]One or more Taiwan cities or counties to search. Search mode only.
rentKindstring"any"Rental dwelling type: whole, suite, shared-suite, single-room, or parking. Rent section only; applies in both Search mode and URL mode.
layoutstring"any"Rent, Search mode only. Bedroom count: 1, 2 or 3.
keywordstringemptyRent, Search mode only. Free-text keyword passed to 591 (a station or district name works well).
sortBystring"default"Rent lists (Search mode and pasted rent list URLs): newest, oldest, price-asc, area-asc, area-desc. Other sections keep the site order.
maxItemsPerUrlintegeremptyURL mode only. Caps the rows taken from each pasted URL.
minPriceinteger(none)Minimum price, in the same unit the listing shows: TWD per month for Rent, 萬 (10,000 TWD) for Sale, Land, and Commercial. Applies in Search mode and URL mode, including a pasted list URL (a pasted single-listing URL is always returned).
maxPriceinteger(none)Maximum price, same unit as Min price. Applies in Search mode and URL mode, including a pasted list URL (a pasted single-listing URL is always returned).
minAreainteger(none)Minimum floor area in 坪 (ping, about 3.3 square meters). Applies in Search mode and URL mode.
maxAreainteger(none)Maximum floor area in 坪 (ping). Applies in Search mode and URL mode.
urlsarrayone example per supported shape (see "URL mode")One or more 591 URLs: rent, sale, land, commercial list pages, single listing pages, and new-build project pages. URL mode only. Also accepted as startUrls; when both are sent and urls is the untouched example default, only startUrls is used. Pagination starts at the page in the URL and walks forward.
fetchDetailsbooleantrueVisit each listing's detail page for the full field set: description, contact details, lease rules, deposit, fees, nearby transit, and the full photo gallery. Turn off for a faster, cheaper, list-level-only run.
maxListingsinteger20Cap on the whole run, split evenly across the regions or URLs you list. 0 means unlimited.
maxPagesinteger0Safety bound on result pages walked per region or URL. 0 (default) means unlimited: the walk stops on its own once a page comes back empty or repeats listings already collected, or sooner once Max total listings is reached.
resumeFromRunIdstring(none)Paste a previous run ID or dataset ID to continue one specific interrupted walk: listings it already saved are loaded and skipped, so this run only appends new listings.
incrementalModebooleanfalseTurn on for recurring monitoring of the same search. The first run returns everything as NEW; later runs return only NEW and UPDATED listings, unchanged ones are suppressed. REAPPEARED needs emitExpired plus a prior full, uncapped scan, see "Resume and recurring updates" above.
stateKeystring(none)Optional name for a monitoring campaign, to keep its incremental state stable or deliberately share it. Auto derived from the section, regions or URLs, and filters when left empty.
emitExpiredbooleanfalseIncremental mode only. Also return listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the tracked search.
ignoreFieldsForChangesstring[][]Incremental mode only. Field names left out of change detection (kept in the output). A bare name matches at any depth, a dotted path such as nearbyTransit.distance matches one nested field.
proxyobjectprefill {"useApifyProxy": true}Connection configuration. Defaults to the lower cost connection tier; a more robust tier is used automatically as a fallback.
maxResidentialRequestsinteger200Caps how many requests may use the more robust connection tier during automatic fallback. 0 turns off the automatic fallback to that tier.
mcpConnectorsarray(none)Optional: send a summary of each listing to apps authorized under Apify Integrations (Notion, Linear, Airtable, or Apify).
notionParentPageUrlstring(none)Notion connector only: the page under which listing pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"id": 99999999,
"section": "rent",
"listingType": "rent",
"url": "https://rent.591.com.tw/99999999",
"title": "Sample Listing Title",
"description": "Full listing description appears here when fetchDetails is on.",
"price": 18000,
"priceText": "18,000",
"priceUnit": "元/月",
"deposit": "押金二個月",
"kindName": "整層住家",
"room": "2房1廳",
"area": 18,
"floor": "5F",
"regionName": "台北市",
"sectionName": "中山區",
"address": "中山區 Sample Rd",
"latitude": 25.0600,
"longitude": 121.5300,
"communityName": "Sample Community",
"facilities": ["冰箱", "洗衣機", "冷氣", "網路"],
"nearbyTransit": [{ "type": "subway", "name": "Sample Station", "distance": 300 }],
"tags": ["新上架", "可開伙"],
"photoCount": 12,
"coverPhoto": "https://img1.591.com.tw/house/0000/000000000.jpg",
"postedAt": "此房屋在3天前發佈",
"contactName": "Sample Agent",
"contactRole": "仲介",
"contactMobile": "0900000000",
"contactLine": "sample-line-id",
"isAgent": true,
"scrapedAt": "2026-01-01T00:00:00.000Z"
}

Output views

The dataset has three views, open them from the run's Output tab or add ?view=<name> to the API items URL:

  • overview: one row per listing with title, URL, price, kind, rooms, area, region, address, coordinates, main contact, photo count, and the incremental columns (changeType, changedFields, firstSeenAt, lastSeenAt).
  • detail: the full-record fields from the detail page: price text, deposit, floor, community, description, every contact field, nearby transit, facilities, fees, lease term, and rules.
  • changes: the incremental view, with changeType, changedFields, first and last seen timestamps, price, and unit.

Runs with several regions or URLs also save a per-search count summary under the OUTPUT key of the run's key-value store, so the output link always resolves.

Plan Requirement

No special plan is needed to read 591.com.tw. In testing, a datacenter-class connection loaded both list pages and listing pages with real content and no challenge, and the default connection tier is the lower cost one. If a connection is refused, the run retries with a different one and escalates to the more robust residential tier only when the default tier is repeatedly refused, capped by maxResidentialRequests, then returns to the default tier once the connection is healthy. Heavy or frequent runs were not load-tested, so for those pick the more robust tier directly under Connection.

Apify free plans do not include residential proxies. If the run needs that tier and your plan lacks it, the log says: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." When no page could be loaded at all, the run ends as failed instead of returning an empty success, with one of these messages:

  • "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 you entered your own proxy URLs, check that their credentials are valid."
  • "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested 591 pages. Upgrade your plan or supply your own proxy URLs, then try again."
  • "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."

A search that loads fine but matches nothing finishes normally with an empty dataset.

FAQ

How much does it cost?

Billing is pay per event, at the rates shown on the Pricing tab. The events are: apify-actor-start (once per run), apify-default-dataset-item (once per listing row delivered to the dataset), and detail-enrichment (once per listing whose detail page was fetched, when Visit each listing's detail page is on, the default). Turn details off for a cheaper list-level run. In Incremental mode, suppressed unchanged listings are not charged. Use Max total listings to cap the cost of any run.

This actor collects only publicly available property listing data. You are responsible for how you use it: follow 591.com.tw's terms and the laws that apply to you, and get legal advice before any commercial redistribution, especially of contact details.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only NEW and UPDATED listings; unchanged ones are suppressed and not billed. Turn on Emit expired too, and once a run has scanned the whole search end to end, a listing that reappears afterward comes back as REAPPEARED.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted run, so you don't re-scrape what it already saved. Incremental mode is for running the exact same search again and again, for example daily, and getting back only what changed since last time; it remembers state itself, so you never paste a run ID.

Why did my run return no listings?

Check your filters and region first. If 591.com.tw refused the connection for the whole run, the log says so and the run still finishes with an empty dataset rather than failing; run it again in a few minutes, or switch to the more robust connection tier if you are consistently blocked.

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 listing into Notion, Linear, or Airtable.

🔗 Want more real estate data?

Pair this actor with these related scrapers from the same team:

🏠 Apartments.com Scraper
Scrape Apartments.com rentals by city, ZIP, neighborhood, address or URL. Extract rent...
🏠 PropertyGuru MY Scraper
Scrape PropertyGuru.com.my sale and rental listings with 30+ structured fields, including...
🏠 Commercial Property AU Scraper
Scrape Australian commercial property listings with full detail data. Extract...
🏠 DDproperty Thailand Scraper
Scrape DDproperty.com Thailand listings at scale. Extract prices, property features...
🏠 REIWA Scraper
Scrape REIWA.com.au across sale, rental, sold, commercial, business and rural properties...
🚗 Dubizzle.com Scraper
Scrape dubizzle.com across the UAE for property, motors, and agent listings. Search by...

👉 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.