
Emma Foster
Machine Learning Engineer

AntiCloudflareTask dengan proxy statis atau sticky dan agen pengguna Chrome yang konsisten.cf_clearance, kredensial proxy, dan konten halaman mentah di penyimpanan sementara, bukan di analitik atau konteks model.Pemantauan harga properti hanya dapat diandalkan jika setiap pengamatan memiliki makna dan asal yang jelas. Harga tawar sebuah listing bukanlah penjualan yang direkam, valuasi otomatis bukanlah transaksi, dan indeks pasar tidak dapat dianggap sebagai kutipan tingkat properti. Pipeline yang paling kuat dimulai dari dataset resmi dan feed lisensi, normalisasi identitas properti dan jenis harga, serta hanya menggunakan halaman publik yang diizinkan untuk celah yang ditentukan. Jika tantangan Cloudflare yang didukung menggantikan halaman listing yang diharapkan, CapSolver dapat menyediakan langkah pemulihan yang terkendali, tetapi alur kerja harus mempertahankan proxy, agen pengguna Chrome, lingkup cookie, dan kebijakan sumbernya. Panduan ini mencakup hierarki sumber data, skema pengamatan, aturan keterbandingan, deteksi tantangan, AntiCloudflareTask, pemulihan sesi sementara, konfirmasi perubahan harga, kontrol kualitas, dan penggunaan yang bertanggung jawab.
Tugas pemantauan properti harus menentukan sinyal yang tepat yang dibutuhkan. Contoh termasuk:
Jangan menggabungkan pertanyaan ini menjadi satu bidang harga umum.
monitoring_job = {
"canonical_property_id": "prop_83f12",
"market": "US-CA-San-Francisco",
"source_priority": [
"official_transaction_dataset",
"licensed_listing_feed",
"partner_api",
"authorized_public_page",
],
"price_types": ["ASKING_SALE", "RECORDED_SALE"],
"alert_rules": {
"asking_change_percent": 3.0,
"status_changes": ["ACTIVE_TO_PENDING", "PENDING_TO_SOLD"],
},
}
Blog CapSolver web-scraping menutupi pola pipeline data terkait, dan CapSolver web-scraping FAQ menyediakan panduan operasional untuk pengumpulan data publik yang diizinkan.
Data resmi dan lisensi harus menjadi lapisan utama. Agency Perumahan Nasional Amerika Serikat House Price Index adalah kumpulan indeks penjualan ulang yang publik yang mencakup berbagai tingkat geografis. Ini bernilai untuk benchmark pasar, tetapi bukan feed listing tingkat properti.
Untuk data transaksi yang direkam, gunakan lembaga registrasi tanah, pencatat, atau pemasok lisensi yang relevan. Data Price Paid Data pemerintah Inggris adalah contoh dataset transaksi resmi. API listing multi-atau portal lisensi mungkin menyediakan pengamatan harga tawar dan status saat ini di bawah kontrak mereka sendiri.
| Sumber | Makna harga | Peran yang direkomendasikan | Keterbatasan utama |
|---|---|---|---|
| Indeks harga resmi | Tren pasar | Konteks benchmark dan anomali | Bukan tingkat properti |
| Catatan transaksi publik | Penjualan yang direkam | Verifikasi dan sejarah | Penundaan publikasi bervariasi |
| Feed listing lisensi | Harga tawar dan status saat ini | Sumber utama listing aktif | Batasan kontrak dan cakupan |
| API mitra | Bidang komersial yang didefinisikan | Sumber operasional terstruktur | Semantik khusus pemasok |
| Halaman publik yang diizinkan | Validasi untuk pembeli | Penutup celah dan QA | Validasi tata letak dan lalu lintas |
Pengumpulan browser harus menjadi fallback untuk celah data yang terdokumentasi, bukan pengganti feed lisensi yang tersedia.
Identitas properti sulit karena alamat berubah format, unit bisa dilewati, dan satu bangunan bisa berisi banyak parcel.
from dataclasses import dataclass
@dataclass(frozen=True)
class PropertyIdentity:
canonical_property_id: str
country: str
administrative_area: str
locality: str
postal_code: str
street_number: str
street_name: str
unit: str | None
parcel_id: str | None
latitude: float | None
longitude: float | None
Kaitkan catatan secara konservatif. Identifikasi parcel atau hak lebih kuat daripada alamat yang dinormalisasi; identifikasi unit yang tepat lebih kuat daripada koordinat tingkat bangunan. Arahkan pencocokan ambigu ke tinjauan.
Garis panduan web-data CapSolver Python menawarkan konteks implementasi untuk pipeline ekstraksi terstruktur.
from dataclasses import dataclass, field
from datetime import datetime, timezone
@dataclass
class PriceObservation:
canonical_property_id: str
source: str
source_record_id: str | None
source_url: str | None
price_type: str
amount: float
currency: str
area_value: float | None
area_unit: str | None
status: str | None
market: str
evidence_hash: str
parser_version: str
observed_at: str = field(
default_factory=lambda: datetime.now(timezone.utc).isoformat()
)
Gunakan kamus jenis harga yang terkendali:
PRICE_TYPES = {
"ASKING_SALE",
"RECORDED_SALE",
"ASKING_RENT_MONTHLY",
"VALUATION_ESTIMATE",
"PRICE_PER_AREA",
"MARKET_INDEX",
}
Jangan membandingkan ASKING_SALE secara langsung dengan RECORDED_SALE atau VALUATION_ESTIMATE. Pertahankan mata uang dan satuan area.
Tantangan dapat mengembalikan halaman antara alih-alih halaman properti yang diharapkan. Jangan menginterpretasi pemilihan harga yang hilang sebagai delisting atau nilai nol.
async def classify_property_page(page, expected_selector: str) -> str:
if await page.locator(expected_selector).count():
return "PROPERTY_PAGE"
title = (await page.title()).strip().lower()
html = (await page.content()).lower()
if "just a moment" in title:
return "CLOUDFLARE_CHALLENGE"
if "challenge-platform" in html or "cf-chl-" in html:
return "CLOUDFLARE_CHALLENGE"
if "listing no longer available" in html:
return "LISTING_UNAVAILABLE"
return "UNKNOWN_PAGE"
Jaga fixture khusus sumber. Marker umum adalah petunjuk rute, bukan bukti bahwa setiap target dapat atau harus dipulihkan.
Halaman produk CapSolver Cloudflare menjelaskan layanan yang didukung, dan blog CapSolver Cloudflare berisi panduan implementasi tambahan.
Dokumentasi Cloudflare Challenge CapSolver mendefinisikan AntiCloudflareTask.
| Field | Wajib | Penggunaan pemantauan properti |
|---|---|---|
type |
Ya | AntiCloudflareTask |
websiteURL |
Ya | Halaman listing atau catatan publik yang disetujui |
proxy |
Ya | Proxy statis atau sticky yang digunakan untuk sesi permintaan |
userAgent |
Opsional | Agen pengguna Chrome yang didukung |
html |
Kondisional | HTML tantangan segar dari sesi sticky yang sama |
Solusi dapat berisi cf_clearance, token, dan agen pengguna. Nilai-nilai ini adalah runtime sementara, bukan data properti.
Dokumentasi Cloudflare menjelaskan peran mekanisme tantangan. Kemampuan pemulihan tidak mengubah izin sumber atau batasan kontraktual.
import os
from urllib.parse import urlparse
SOURCE_POLICY = {
"approved-listings.example": {
"purpose": "asking-price-validation",
"proxy_profile": "property_us_west",
"max_checks_per_hour": 2,
},
}
PROXY_VAULT = {
"property_us_west": os.environ["PROPERTY_PROXY_US_WEST"],
}
def approved_source(url: str) -> dict:
host = urlparse(url).hostname
policy = SOURCE_POLICY.get(host)
if not policy:
raise PermissionError("Sumber properti tidak disetujui")
return policy
URL target harus berasal dari catatan sumber yang terdaftar, bukan teks bebas yang diberikan model atau pengguna dalam scheduler produksi.
AntiCloudflareTaskimport capsolver
capsolver.api_key = os.environ["CAPSOLVER_API_KEY"]
def solve_property_page_challenge(
url: str,
chrome_user_agent: str,
fresh_html: str = "",
) -> dict:
policy = approved_source(url)
proxy = PROXY_VAULT[policy["proxy_profile"]]
task = {
"type": "AntiCloudflareTask",
"websiteURL": url,
"proxy": proxy,
"userAgent": chrome_user_agent,
}
if fresh_html:
task["html"] = fresh_html
solution = capsolver.solve(task)
cookies = solution.get("cookies") or {}
clearance = cookies.get("cf_clearance") or solution.get("token")
if not clearance:
raise RuntimeError("Solusi Tantangan Cloudflare tidak lengkap")
return {
"cookies": cookies,
"user_agent": solution.get("userAgent") or chrome_user_agent,
"proxy_profile": policy["proxy_profile"],
}
Gunakan proxy statis atau sticky dan pertahankan untuk permintaan awal, pembuatan tugas, dan pemulihan halaman. Jangan masukkan kredensial proxy ke log.
Dokumentasi resmi CapSolver memerlukan klien permintaan yang mendukung TLS dan detail sesi yang konsisten. Pertahankan implementasi ini di adapter sumber yang telah diuji.
async def recover_property_document(
source_adapter,
url: str,
challenge_html: str,
user_agent: str,
) -> str:
solution = solve_property_page_challenge(
url=url,
chrome_user_agent=user_agent,
fresh_html=challenge_html,
)
response = await source_adapter.fetch_with_session(
url=url,
proxy_profile=solution["proxy_profile"],
user_agent=solution["user_agent"],
cookies=solution["cookies"],
)
if response.status_code != 200:
raise RuntimeError("Permintaan yang dipulihkan tidak mengembalikan HTTP 200")
if "challenge-platform" in response.text.lower():
raise RuntimeError("Tantangan tetap setelah satu upaya pemulihan")
return response.text
fetch_with_session adalah adapter yang dimiliki aplikasi yang menggunakan profil TLS yang disetujui. Ini tidak boleh mengekspos cookie, nilai proxy, atau header ke analitik.
Halaman publik bervariasi. Gunakan satu adapter per sumber yang disetujui dengan selektor dan pemeriksaan semantik yang jelas.
from decimal import Decimal, InvalidOperation
class SourceAdapter:
source_name = "approved-listings"
parser_version = "2026-08-28.1"
def parse_asking_price(self, document) -> dict:
raw = document.select_one('[data-testid="asking-price"]')
if raw is None:
raise ValueError("Bidang harga tawar tidak ditemukan")
currency = raw.get("data-currency")
amount_text = raw.get("data-amount")
try:
amount = Decimal(amount_text)
except (InvalidOperation, TypeError):
raise ValueError("Jumlah harga tawar tidak valid")
if amount <= 0 or not currency:
raise ValueError("Pengamatan harga tawar tidak lengkap")
return {
"price_type": "ASKING_SALE",
"amount": float(amount),
"currency": currency,
}
Jangan anggap estimasi pemasaran, ilustrasi hipotek bulanan, atau "dari" harga sebagai harga tawar.
from decimal import Decimal
def comparable(left: PriceObservation, right: PriceObservation) -> bool:
return all([
left.canonical_property_id == right.canonical_property_id,
left.price_type == right.price_type,
left.currency == right.currency,
left.market == right.market,
])
def percentage_change(previous: float, current: float) -> float:
if previous <= 0:
raise ValueError("Harga sebelumnya harus positif")
return float(
(Decimal(str(current)) - Decimal(str(previous)))
/ Decimal(str(previous))
* 100
)
Jika area berubah, unit ditambahkan, atau listing dipasang kembali di bawah identitas properti yang berbeda, minta tinjauan daripada melaporkan pergerakan harga yang salah.
Pengamatan tunggal bisa bising. Gunakan konfirmasi berulang atau koroborasi sumber.
def confirmed_price_change(
observations: list[PriceObservation],
threshold_percent: float,
) -> dict | None:
if len(observations) < 3:
return None
baseline, first_new, second_new = observations[-3:]
if not comparable(baseline, first_new):
return None
if not comparable(first_new, second_new):
return None
if first_new.amount != second_new.amount:
return None
change = percentage_change(baseline.amount, second_new.amount)
if abs(change) < threshold_percent:
return None
return {
"event": "CONFIRMED_PRICE_CHANGE",
"previous": baseline.amount,
"current": second_new.amount,
"currency": second_new.currency,
"change_percent": round(change, 2),
}
Untuk dataset transaksi, gunakan timestamp publikasi dan kebijakan revisi sumber alih-alih konfirmasi browser berulang.
| Event | Makna | Tujuan |
|---|---|---|
PRICE_CHANGE_CONFIRMED |
Pengamatan harga yang dapat dibandingkan berubah | Pemberitahuan analis atau pelanggan |
STATUS_CHANGED |
Status aktif, menunggu, terjual, atau dihapus berubah | Alur kerja listing |
CHALLENGE_ENCOUNTERED |
Sumber menampilkan tantangan yang didukung | Dashboard otomasi |
RECOVERY_FAILED |
Pemulihan tidak mengembalikan halaman yang diharapkan | Tinjauan operator |
PARSER_UNKNOWN |
Halaman dikembalikan tetapi semantik harga tidak jelas | Antrian kualitas data |
SOURCE_STALE |
Feed resmi atau halaman tidak diperbarui | Monitor kesehatan sumber |
Jangan ubah tantangan, timeout, atau kesalahan parser menjadi harga nol atau status delisting.
The FAQ kesalahan CapSolver menyediakan kategori diagnostik, dan blog otomasi CapSolver membahas pola pemulihan terkait.
Kode Bonus: Gunakan kode WEBS di Dasbor CapSolver untuk mendapatkan bonus tambahan 5% pada setiap isi ulang.
| Kontrol | Implementasi yang Direkomendasikan |
|---|---|
| Akses Sumber | Kontrak atau persetujuan tertulis yang terkait dengan tujuan |
| Prioritas Sumber | Data resmi/ mitra sebelum fallback halaman |
| Cakupan Target | Daftar putih host dan path |
| Proxy | Profil server sisi server statis atau sticky |
| User Agent | Identitas Chrome yang didukung sama melalui pemulihan |
| Pengulangan Tantangan | Satu kali upaya, lalu tinjau |
| Semantik Harga | Jenis harga, mata uang, unit, dan status yang jelas |
| Bukti | ID sumber, timestamp, versi parser, dan hash |
| Pemberitahuan | Perubahan komparabel yang dikonfirmasi saja |
| Retensi | Cookie berumur pendek; pengamatan properti yang diatur |
Gunakan halaman produk CapSolver untuk meninjau kategori yang didukung dan FAQ penyelesaian CAPTCHA CapSolver untuk panduan alur tugas.
Hanya pantau data yang Anda izinkan untuk diakses. Patuhi kontrak feed daftar, lisensi registri, ketentuan sumber, batas kecepatan, hukum privasi, dan persyaratan perumahan adil. Jangan kumpulkan data akun pribadi, detail kontak pemilik, informasi penyewa, catatan aplikasi, atau laporan penilaian terbatas tanpa dasar hukum yang sah. Batasi pemulihan tantangan pada alur kerja publik atau mitra yang disetujui. Kemampuan teknis tidak memberi izin.
Pemantauan harga properti yang andal bergantung pada pengamatan komparabel dan asal yang jelas. Indeks resmi dan dataset transaksi memberikan dasar; feed lisensi menyediakan detail daftar saat ini; halaman yang sah mengisi celah yang ditentukan. Ketika tantangan Cloudflare yang didukung mengganggu fallback tersebut, gunakan CapSolver dengan proxy statis atau sticky, user agent Chrome yang konsisten, cookie berumur pendek, satu upaya pemulihan, dan verifikasi halaman yang jelas.
Mulai alur kerja data properti yang disetujui dengan CapSolver, validasikan terhadap sumber yang dikendalikan, dan tambahkan aturan jenis harga, bukti, dan konfirmasi sebelum memperluas pemberitahuan.
Tidak. Ini adalah indeks pasar yang dibangun dari transaksi berulang dan diterbitkan pada beberapa tingkat geografis. Gunakan sebagai benchmark, bukan sebagai harga daftar individu.
Gunakan tugas AntiCloudflareTask yang terdokumentasi dengan URL tujuan yang tepat dan proxy statis atau sticky. User agent Chrome yang konsisten dan HTML tantangan segar mungkin juga diperlukan.
Mereka harus disimpan sebagai jenis harga yang berbeda. Setiap perbandingan harus menjelaskan bahwa satu adalah tawaran penjual dan yang lain adalah transaksi selesai.
Tidak. Catat kesalahan infrastruktur atau parser dan verifikasi status halaman. Selector yang hilang bukan bukti bahwa daftar dihapus.
cf_clearance harus disimpan?Hanya simpan selama sesi permintaan yang disetujui berumur pendek. Jangan simpan di analitik properti, konteks model, log jangka panjang, atau pemberitahuan pelanggan.
Diagnosa alur tantangan Cloudflare dengan AntiCloudflareTask, proxy yang stabil dan identitas user agent, HTML segar, penanganan clearance, validasi, dan error yang aman.

Bangun pemantauan inventaris e-commerce yang andal dengan sumber API, pemulihan tantangan Cloudflare, konsistensi sesi, bukti persediaan, dan notifikasi aman.
