Data listing properti berubah nyaris setiap hari — harga baru, unit yang laku, listing yang baru naik — dan justru karena data itu bernilai tinggi bagi tim price-monitoring, agensi riset pasar, dan developer yang memantau kompetitor, hampir semua portal properti besar menaruh lapisan CAPTCHA di jalur pengambilan datanya. CaptchaAI menjaga pipeline pengumpulan listing, histori harga, dan indikator pasar Anda tetap berjalan tanpa intervensi manual setiap kali reCAPTCHA, Turnstile, atau Cloudflare Challenge muncul di tengah crawl.
Ragam Proteksi CAPTCHA di Portal Properti
Setiap segmen properti cenderung memakai kombinasi proteksi yang berbeda, tergantung seberapa besar risiko scraping bagi pemilik platform:
| Jenis Platform | Proteksi | Jenis CAPTCHA |
|---|---|---|
| Agregator MLS | Cloudflare Challenge | Tantangan penuh + validasi proxy |
| Portal tipe Zillow | reCAPTCHA v3 | Invisible, berbasis perilaku |
| Direktori agen properti | reCAPTCHA v2 | Checkbox atau invisible |
| Arsip pajak properti | CAPTCHA gambar | Pengenalan teks (OCR) |
| Situs lelang properti | Cloudflare Turnstile | Tantangan widget |
| Listing komersial | reCAPTCHA v2 Enterprise | Verifikasi tingkat lanjut |
Sebagian portal lelang regional juga masih memakai GeeTest v3 di form pendaftaran peserta lelang. CaptchaAI menyelesaikan keenam jenis di atas lewat endpoint API yang sama, jadi Anda tidak perlu logic solver terpisah untuk tiap platform.
Membangun Collector Otomatis untuk Listing Properti
Pola paling stabil untuk scraper properti adalah deteksi-lalu-solve: cek dulu jenis CAPTCHA yang muncul di response, baru kirim task ke CaptchaAI. Contoh Python berikut mendeteksi reCAPTCHA (v2 maupun v3) dan Turnstile dalam satu fungsi fetch(), lalu mem-parsing harga, alamat, kamar tidur/kamar mandi, dan luas bangunan dari HTML yang berhasil diambil:
import requests
import time
import re
import json
import csv
import os
from datetime import datetime
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_captcha(params):
params["key"] = API_KEY
resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
if not resp.text.startswith("OK|"):
raise Exception(f"Submit: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id,
})
if result.text == "CAPCHA_NOT_READY":
continue
if result.text.startswith("OK|"):
return result.text.split("|", 1)[1]
raise Exception(f"Solve: {result.text}")
raise TimeoutError()
class PropertyCollector:
def __init__(self):
self.session = requests.Session()
self.session.headers["User-Agent"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0"
)
def fetch(self, url):
"""Fetch page with automatic CAPTCHA handling."""
resp = self.session.get(url)
# reCAPTCHA
match = re.search(
r'data-sitekey=["\']([A-Za-z0-9_-]+)["\']', resp.text
)
if match:
# Detect v3
is_v3 = "recaptcha/api.js?render=" in resp.text
params = {
"method": "userrecaptcha",
"googlekey": match.group(1),
"pageurl": url,
}
if is_v3:
params["version"] = "v3"
params["action"] = "search"
token = solve_captcha(params)
resp = self.session.post(url, data={
"g-recaptcha-response": token,
})
# Turnstile
if "cf-turnstile" in resp.text:
match = re.search(r'data-sitekey=["\']([^"\']+)', resp.text)
if match:
token = solve_captcha({
"method": "turnstile",
"sitekey": match.group(1),
"pageurl": url,
})
resp = self.session.post(url, data={
"cf-turnstile-response": token,
})
return resp.text
def collect_listings(self, urls):
"""Collect property listings from multiple pages."""
listings = []
for url in urls:
try:
html = self.fetch(url)
page_listings = self._parse_listings(html)
listings.extend(page_listings)
print(f" {len(page_listings)} listings from {url}")
time.sleep(3)
except Exception as e:
print(f" Error: {url} - {e}")
return listings
def _parse_listings(self, html):
"""Extract property data from HTML."""
listings = []
# Price extraction
prices = re.findall(r'\$\s*([\d,]+)', html)
# Address extraction
addresses = re.findall(
r'class="address"[^>]*>(.*?)</(?:div|span|p)', html
)
# Bed/Bath extraction
beds = re.findall(r'(\d+)\s*(?:bed|br|bedroom)', html, re.I)
baths = re.findall(r'(\d+)\s*(?:bath|ba|bathroom)', html, re.I)
# Sqft extraction
sqft = re.findall(r'([\d,]+)\s*(?:sq\s*ft|sqft)', html, re.I)
# Combine available data
count = max(len(prices), len(addresses), 1)
for i in range(min(count, 50)): # Cap at 50 per page
listing = {
"price": prices[i] if i < len(prices) else None,
"address": (
addresses[i].strip() if i < len(addresses) else None
),
"beds": beds[i] if i < len(beds) else None,
"baths": baths[i] if i < len(baths) else None,
"sqft": sqft[i] if i < len(sqft) else None,
"collected_at": datetime.utcnow().isoformat(),
}
if listing["price"] or listing["address"]:
listings.append(listing)
return listings
def export_csv(self, listings, filename):
if not listings:
print("No listings to export")
return
keys = ["price", "address", "beds", "baths", "sqft", "collected_at"]
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(listings)
print(f"Exported {len(listings)} listings to {filename}")
# Usage
collector = PropertyCollector()
search_urls = [
"https://example-realty.com/search?city=austin&type=sale&page=1",
"https://example-realty.com/search?city=austin&type=sale&page=2",
"https://example-realty.com/search?city=austin&type=sale&page=3",
]
listings = collector.collect_listings(search_urls)
collector.export_csv(listings, "austin_listings.csv")
Fungsi solve_captcha() di atas memakai pola submit-lalu-polling standar CaptchaAI: kirim task ke in.php, simpan task_id, lalu polling res.php setiap 5 detik sampai statusnya OK. Method userrecaptcha menangani reCAPTCHA v2 maupun v3 — bedanya cukup di parameter version dan action untuk v3. Kelas PropertyCollector membatasi hasil parsing ke 50 listing per halaman dan menyisipkan jeda 3 detik antar-request supaya pola trafik tetap wajar, bukan burst yang mudah dicurigai sebagai bot.
Kapan Anda Butuh Paket Thread Lebih Besar untuk Scraping Properti
CaptchaAI menagih per thread — jumlah CAPTCHA yang sedang diproses bersamaan — bukan per solve, sehingga biaya scraping properti gampang diprediksi. Ini kabar baik untuk tim yang sensitif terhadap budget, seperti freelancer riset pasar atau agensi data kecil yang selama ini terbiasa dengan tarif per-solve yang naik-turun. Setiap paket menyertakan solve tanpa batas per thread selama satu bulan berjalan, jadi lonjakan volume listing di musim ramai tidak otomatis menaikkan tagihan.
Pemetaan volume yang realistis untuk tim data properti:
- Kolektor solo yang crawl 2-3 portal setiap pagi umumnya cukup dengan BASIC ($15/bulan, 5 thread).
- Agensi kecil yang menjalankan beberapa crawler paralel untuk beberapa kota biasanya naik ke STANDARD ($30/bulan, 15 thread) atau ADVANCE ($90/bulan, 50 thread).
- Tim enterprise yang memantau ribuan listing lintas negara setiap hari umumnya berada di PREMIUM ($170/bulan, 100 thread) ke atas.
Poin Data Properti yang Layak Dikumpulkan
| Bidang | Sumber | Kegunaan |
|---|---|---|
| Harga listing | Halaman properti | Valuasi pasar |
| Alamat | Halaman properti | Analisis geografis |
| Kamar tidur/mandi/luas bangunan | Detail properti | Perbandingan antar-unit |
| Lama waktu di pasar | Metadata listing | Kecepatan penjualan |
| Riwayat harga | Log perubahan harga | Analisis tren |
| Pajak properti | Arsip pajak | Analisis investasi |
| Biaya HOA/iuran lingkungan | Detail listing | Analisis biaya |
Tujuh field ini konsisten dipakai hampir semua tim yang membangun dashboard pasar properti internal — cukup untuk model valuasi sederhana tanpa perlu scraping seluruh halaman.
Alur Analisis Pasar dari Data Listing yang Terkumpul
Setelah listing masuk ke penyimpanan Anda, alur analisisnya biasanya berjenjang tiga tingkat: harian untuk delta harga, mingguan untuk tren median, bulanan untuk skor peluang investasi.
Daily Collection
→ Property listings (500-1000 per market)
→ Price changes (delta from previous day)
→ New listings vs delisted
Weekly Analysis
→ Median price trends
→ Inventory levels
→ Days-on-market averages
→ Price-per-sqft by neighborhood
Monthly Report
→ Market heat map
→ Competitive pricing analysis
→ Investment opportunity scoring
Struktur berjenjang ini memisahkan proses collection — yang butuh solve CAPTCHA di setiap run — dari proses analisis, yang murni bekerja di atas data yang sudah tersimpan. Kegagalan solve di satu run harian jadi tidak merusak laporan mingguan atau bulanan yang sudah jadi.
Kepatuhan Data saat Scraping Properti di Indonesia
UU Pelindungan Data Pribadi (UU PDP 27/2022) dan UU ITE membuat satu aturan praktis relevan untuk tim data properti: kumpulkan data listing publik yang memang ditujukan untuk pencarian, dan hindari mengumpulkan data pribadi penjual, pembeli, atau agen di luar kontak bisnis yang memang dipublikasikan. Artikel ini bukan nasihat hukum — jika model bisnis Anda menyimpan data kontak dalam skala besar, konsultasikan dengan tim legal internal sebelum produksi.
Pertanyaan Umum seputar Scraping Data Properti
Bagaimana alur CaptchaAI menangani reCAPTCHA v3 yang invisible di portal properti?
CaptchaAI membaca sitekey dan parameter action dari halaman, mengirim task dengan method userrecaptcha beserta version: v3, lalu mengembalikan token lewat polling res.php. Token itu langsung Anda kirim balik sebagai g-recaptcha-response — tidak ada interaksi visual karena reCAPTCHA v3 memang tidak menampilkan widget.
Apakah scraping data listing properti legal di Indonesia?
Data listing yang memang dipublikasikan untuk pencarian publik umumnya boleh dikumpulkan. Yang perlu dihindari adalah data pribadi penjual/pembeli di luar kontak bisnis yang dipublikasikan, dan pelanggaran terhadap ketentuan layanan situs sumber — lihat catatan kepatuhan di atas.
Paket CaptchaAI mana yang cocok untuk crawl properti skala besar?
Tergantung jumlah proses paralel, bukan jumlah listing. Tim dengan puluhan worker crawler berjalan bersamaan biasanya perlu ADVANCE ($90/bulan, 50 thread) atau PREMIUM ($170/bulan, 100 thread); tim enterprise lintas negara bisa naik ke CORPORATE ($240/bulan, 150 thread) atau ENTERPRISE ($300/bulan, 200 thread).
Apakah CaptchaAI bisa menyelesaikan CAPTCHA gambar di arsip pajak properti yang lama?
Bisa. Arsip pajak properti pemerintah daerah sering memakai CAPTCHA gambar OCR klasik tanpa JavaScript modern. CaptchaAI menyelesaikannya lewat method post yang sama dipakai untuk CAPTCHA teks biasa, dan biasanya lebih cepat dibanding reCAPTCHA atau Turnstile.
Apakah CaptchaAI bisa menangani hCaptcha untuk portal properti alternatif?
Belum. hCaptcha tidak didukung CaptchaAI saat ini. Sebagian besar portal properti besar memakai reCAPTCHA atau Cloudflare, tapi jika target Anda memang memakai hCaptcha, Anda memerlukan layanan lain untuk jenis itu.
Baca Juga
- Cara memantau harga e-commerce dengan CaptchaAI
- Praktik terbaik setup proxy untuk scraping
- Panduan scraping situs yang dilindungi CAPTCHA