วิธีดึงข้อมูล Redfin ด้วย Python (แบบไม่ให้โดนบล็อก)

อัปเดตล่าสุดเมื่อ April 15, 2026
วิธีดึงข้อมูล Redfin ด้วย Python (แบบไม่ให้โดนบล็อก)

Redfin อัปเดต 70% ของประกาศใหม่จาก MLS ในสหรัฐฯ ภายในห้านาที หลังจากรายการเหล่านั้นถูกส่งเข้าระบบ ความสดระดับนี้นี่แหละที่คนทำ data pipeline ด้านอสังหาฯ ชอบกันสุด ๆ — และก็เป็นเหตุผลว่าทำไมสคริปต์ดึงข้อมูลจำนวนมากถึงพุ่งไปที่ Redfin แล้วโดนบล็อกภายในไม่กี่นาที

ผมทำงานกับเครื่องมือดึงข้อมูลที่ Thunderbit มาหลายปี และบอกได้เลยว่า: ช่องว่างระหว่าง "ดึงข้อมูลจาก Redfin" กับ "ดึงข้อมูลจาก Redfin โดยไม่โดนบล็อก" นี่แหละคือจุดที่บทความสอนส่วนใหญ่พัง พวกเขามักโชว์แค่โค้ด BeautifulSoup แล้วข้ามเรื่องที่ Cloudflare ตอบโต้คำขอของคุณแบบหนัก ๆ จากนั้นก็ปล่อยให้คุณนั่งมอง error 403 แบบงง ๆ ว่าพลาดตรงไหน คู่มือนี้ไม่ใช่แบบนั้น ผมจะพาคุณดู 3 แนวทางจริง — การ parse HTML, การใช้ API ที่ซ่อนอยู่ของ Redfin และแนวทางไม่ต้องเขียนโค้ดด้วย Thunderbit — พร้อมเจาะเรื่องระบบป้องกันบอทที่สำคัญจริง ๆ พออ่านจบ คุณจะรู้เลยว่าแต่ละวิธีเหมาะกับทักษะ ขนาดงาน และระดับความขี้เกียจในการดูแลระบบของคุณแบบไหน

ลองใช้ Thunderbit สำหรับดึงข้อมูล Redfin

Redfin คืออะไร และทำไมข้อมูลของมันถึงสำคัญ?

Redfin คือบริษัทนายหน้าอสังหาริมทรัพย์สายเทคโนโลยี มีเอเจนต์เงินเดือนประจำที่ดึงประกาศจากฟีด MLS โดยตรง ครอบคลุม เมืองใหญ่กว่า 100 แห่งในสหรัฐฯ และแคนาดา ครอบคลุม 42 รัฐ และมีผู้เข้าชมเกือบ 50 ล้านคนต่อเดือน ต่างจากพอร์ทัลที่เป็นแค่ตัวรวบรวมข้อมูล Redfin ใช้ข้อมูลที่เอเจนต์ยืนยันแล้ว และ Redfin Estimate AVM ของบริษัทครอบคลุม มากกว่า 95 ล้านทรัพย์สิน โดยมีค่าคลาดเคลื่อนมัธยฐานเพียง 1.96% สำหรับบ้านที่กำลังอยู่ในตลาด

redfin_stats_f3c7fb5cbd.png

การผสมกันของข้อมูลที่สดใกล้เคียง MLS คุณภาพที่ยืนยันโดยนายหน้า และ AVM ที่แม่นสูง ทำให้นักลงทุนอสังหาฯ เอเจนต์ สตาร์ทอัพ proptech และนักวิเคราะห์ข้อมูล ต่างต้องการเข้าถึงข้อมูล Redfin แบบโปรแกรมได้ Python เลยเป็นตัวเลือกที่เหมาะสุดสำหรับงานนี้ เพราะ ecosystem ด้าน scraping พร้อมมากอยู่แล้ว (requests, BeautifulSoup, Selenium, Playwright) ชุมชนผู้ใช้ก็ใหญ่ และต่อกับ pandas กับ Jupyter เพื่อวิเคราะห์ต่อได้ทันที

ทำไมต้องดึงข้อมูล Redfin ด้วย Python?

กรณีใช้งานมีหลากหลายพอ ๆ กับคนที่ต้องใช้ข้อมูล ต่อไปนี้คือวิธีที่กลุ่มผู้ใช้ต่าง ๆ เอาข้อมูลจาก Redfin ไปใช้กันเป็นหลัก:

กลุ่มผู้ใช้เป้าหมายหลักในการดึงข้อมูลตัวอย่างการใช้งาน
เอเจนต์อสังหาฯหา lead, วิเคราะห์ตลาดประกาศใหม่และประกาศหมดอายุในพื้นที่ให้บริการ; ไดเรกทอรีเอเจนต์เพื่อเทียบคู่แข่ง
นักลงทุนอสังหาฯหาโอกาสลงทุน, วิเคราะห์ cap rateคัดกรองผลตอบแทนค่าเช่า, หาอสังหาฯ ราคาต่ำกว่าตลาด, แจ้งเตือนประกาศใหม่รายวัน
สตาร์ทอัพ PropTechสร้าง data pipeline สำหรับผลิตภัณฑ์ข้อมูลฝึก AVM, dashboard ตลาด, ระบบซื้อทรัพย์เพื่อขายต่อ
นักวิเคราะห์ข้อมูลวิจัยตลาด, BIแนวโน้มราคากลางระดับ ZIP code, time series ของวันค้างตลาด, อัตราส่วนราคาขายต่อราคาตั้ง
Wholesaler / Flipperติดตามอสังหาฯ มีปัญหาตรวจจับการลดราคา, foreclosures, เปรียบเทียบออฟมาร์เก็ต

เทรนด์ภาพรวมก็ยืนยันเรื่องนี้เหมือนกัน: กว่า 72% ของบริษัทอสังหาฯ ใช้ predictive analytics เพื่อหาโอกาสและบริหารความเสี่ยง ตลาด PropTech คาดว่าจะโตถึง $47 พันล้านในปี 2025 ด้วยอัตราเติบโตเฉลี่ยต่อปี 16.4% ข้อมูลอสังหาฯ แบบมีโครงสร้างเลยไม่ใช่ของฟุ่มเฟือยอีกต่อไป — แต่มันคือของจำเป็นพื้นฐาน

ฟิลด์ข้อมูล Redfin ทั้งหมดที่คุณดึงได้ (อ้างอิงครบ)

ก่อนเขียนโค้ดแม้แต่บรรทัดเดียว คุณต้องรู้ก่อนว่ามีข้อมูลอะไรให้ใช้บ้าง ผมได้ไล่ดูหน้าผลการค้นหา หน้ารายละเอียดทรัพย์สิน และหน้าโปรไฟล์เอเจนต์ของ Redfin แล้ว เทียบกับ wrapper โค้ดเปิดอย่าง Stingray API เช่นโปรเจกต์ reteps/redfin และ RedfinPlus รวมแล้วนับได้ 117 ฟิลด์ที่แตกต่างกัน ครอบคลุมหลายประเภทของหน้า

ตารางนี้ควร bookmark ไว้เลย การรู้ schema ของข้อมูลตั้งแต่ต้นจะช่วยประหยัดเวลาหา selector แบบลองผิดลองถูกไปได้หลายชั่วโมง

ฟิลด์ในหน้าผลการค้นหา

นี่คือฟิลด์แบบเบาที่อยู่บนการ์ดประกาศ ซึ่งมักดึงได้โดยไม่ต้อง render JavaScript แบบเต็ม:

ฟิลด์ชนิดข้อมูลหมายเหตุ
Property IDNumberรหัสภายในของ Redfin, แยกจาก /home/{id} ใน href
List priceNumber
ที่อยู่เต็มText
ห้องนอน / ห้องน้ำ / ตารางฟุตNumberสามค่าที่เรียงกัน
ประเภททรัพย์สินSingle SelectSFH, Condo, Townhouse, Multi
สถานะTextActive, Pending, Contingent
จำนวนวันในตลาดNumber
ตัวบ่งชี้ลดราคาNumberส่วนต่างจากราคาเริ่มต้น
รูปหลักImage URLหนึ่งรูปต่อการ์ด
ป้าย Hot HomeBoolean
วัน/เวลาเปิดบ้านText
ข้อมูลนายหน้าText

ฟิลด์ในหน้ารายละเอียดทรัพย์สิน

หน้ารายละเอียดคือส่วนที่มีข้อมูลลึกจริง ๆ ฟิลด์หลายอย่างต้องใช้ JavaScript rendering หรือ Stingray API:

ฟิลด์ชนิดข้อมูลหมายเหตุ
Redfin Estimate (on-market)Numberผ่าน /stingray/api/home/details/avm
Redfin Estimate (off-market)Numberผ่าน /stingray/api/home/details/owner-estimate; ค่าคลาดเคลื่อนมัธยฐาน 7.52%
ปีที่สร้าง / ปรับปรุงNumber
ขนาดที่ดินNumber
ค่าส่วนกลาง HOANumberรายเดือน ถ้ามี
ภาษีทรัพย์สิน (รายปี)Number
มูลค่าประเมินภาษีNumber
ตารางประวัติการขายTableราคา, วันที่, ประเภทเหตุการณ์
คำอธิบายทรัพย์สินTextย่อหน้าเชิงการตลาด
URL รูปภาพ (carousel)Image URLsมากกว่า 20 รูปต่อหนึ่งประกาศ
ชื่อเอเจนต์ เบอร์โทร อีเมลText / Phone / Emailเบอร์มักถูกปิดบางส่วน
คะแนนโรงเรียน (ประถม/มัธยมต้น/มัธยมปลาย)Numberพร้อมชื่อเขตพื้นที่
Walk / Transit / Bike ScoreNumber
คะแนนความเสี่ยงด้านสภาพภูมิอากาศNumberน้ำท่วม ไฟป่า ความร้อน ลม
บ้านที่คล้ายกันที่ active / sold / ใกล้เคียงURLsข้อมูลจาก carousel
ที่จอดรถ โรงรถ ระบบทำความร้อน ระบบทำความเย็นTextกลุ่มสิ่งอำนวยความสะดวก

ฟิลด์ในหน้าโปรไฟล์เอเจนต์

ฟิลด์ชนิดข้อมูลหมายเหตุ
ชื่อเอเจนต์ รูป โปรไฟล์นายหน้า ประวัติย่อText / Image
โทรศัพท์ / ฟอร์มติดต่อPhone / Textต้องคลิกเพื่อแสดง
จำนวนประกาศที่ activeNumber
ยอดขาย 12 เดือนล่าสุด / มูลค่ารวมNumber
อัตราส่วนราคาเฉลี่ยจากตั้งขายถึงปิดการขายNumber
ดาวรีวิว / จำนวนรีวิวNumber
ปีประสบการณ์ / เลขใบอนุญาตText / Number

เมื่อคุณใช้ฟีเจอร์ AI Suggest Fields ของ Thunderbit บนหน้า Redfin ระบบจะตรวจจับคอลัมน์ส่วนใหญ่ให้อัตโนมัติและกำหนดชนิดข้อมูลให้ถูกต้อง — ไม่ต้อง map CSS selector เองทีละอัน เดี๋ยวผมจะอธิบายต่อด้านล่าง

ถอดรหัสระบบป้องกันบอทของ Redfin (ไม่ใช่แค่ "ใช้ proxy")

ตรงนี้ผมอยากย้ำไว้ เพราะบทสอนส่วนใหญ่ชอบข้ามปัญหาการโดนบล็อก แล้วกระโดดไปที่ "ไปซื้อ proxy จากสปอนเซอร์เรา" ซึ่งไม่ช่วยอะไร ถ้าคุณไม่เข้าใจว่า Redfin ตรวจจับสคริปต์ดึงข้อมูลยังไง คุณก็จะเผาเครดิต proxy ไปเรื่อย ๆ แล้วสุดท้ายยังโดนบล็อกอยู่ดี ScrapeOps ให้คะแนนความยากของ anti-bot ของ Redfin ไว้ 7.5 จาก 10 และ Scraperly จัดอยู่ในระดับกลาง (3/5) — "ไม่ดุเท่า enterprise WAF ของ Zillow โดยอาศัย rate limiting แบบกำหนดเองและ JavaScript challenge"

Redfin ใช้สแต็กป้องกันหลายชั้น: Cloudflare ที่ขอบเครือข่าย (JS challenge, Turnstile, TLS/JA3 fingerprinting) ร่วมกับ ตัวจำกัดความถี่ระดับแอปของ Redfin เอง ไม่มีคำสั่ง Crawl-delay ใน robots.txt เพราะการบังคับใช้เกิดที่ชั้น WAF

ทำไม requests + BeautifulSoup แบบง่าย ๆ ถึงใช้ไม่ได้กับ Redfin

ถ้าคุณส่ง requests.get() ธรรมดาไปยังหน้าทรัพย์สินของ Redfin ด้วย header ค่าเริ่มต้น สิ่งที่มักเกิดขึ้นคือ:

  • HTTP 403 — Cloudflare JS challenge ไม่ผ่าน คุณจะได้หน้า challenge แทนประกาศจริง
  • หน้าท้าทายคั่นกลาง — body ของ HTML มี widget Turnstile ของ Cloudflare ไม่ใช่ข้อมูลทรัพย์สิน
  • HTTP 200 แต่ HTML มาไม่ครบ — คุณจะได้โครงหน้าแบบ shell พร้อม JSON blob ฝังอยู่ใต้ root.__reactServerState.InitialContext แต่ไม่มีการ์ดค้นหาที่ render แล้ว ไม่มีประวัติราคา ไม่มีคะแนนโรงเรียน

Redfin ใช้ React SSR framework ของตัวเอง (ไม่ใช่ Next.js) และคีย์ hydration ก็เป็นแบบเฉพาะของ Redfin — root.__reactServerState.InitialContext โดยข้อมูลประกาศอยู่ใต้ ReactServerAgent.cache.dataCache ซึ่งไม่ใช่ __NEXT_DATA__ หรือ window.__INITIAL_STATE__

สาเหตุที่เจอ 403 แบบเงียบ ๆ บ่อยที่สุดคืออะไร? ขาด header Sec-Fetch-* Redfin/Cloudflare ตรวจสอบ Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest และ Sec-Fetch-User โดยตรง ถ้าไม่มี ระบบจะติดธงทันที

แผนรับมือ: หน่วงเวลา, Header, Proxy และ Session

นี่คือสรุปการป้องกันแต่ละชั้น พร้อมวิธีรับมือของแต่ละแบบ:

กลไกป้องกันของ Redfinทำอะไรสัญญาณที่ใช้ตรวจจับวิธีรับมือ
Cloudflare JS challengeหน้าแทรกที่ออกคุกกี้ cf_clearance403 + body เป็น HTML ของ Cloudflareใช้ curl_cffi พร้อม impersonate="chrome120"; วอร์ม session ผ่านหน้าแรก; ใช้ US residential proxy
Cloudflare TurnstileCAPTCHA แบบโต้ตอบใน session ที่เสี่ยงสูง403 + widget Turnstileใช้ headless browser แบบ stealth + residential proxy
Cloudflare Error 1020 (แบนตาม ASN)บล็อก IP/ASN ที่ถูกระบุว่ามีความเสี่ยงใน WAFbody 403 ขึ้น "Error 1020 Access Denied"เปลี่ยนไปใช้ residential/mobile proxy; อย่าใช้ datacenter ASN
TLS/JA3 fingerprintingตรวจจับ TLS stack ที่ไม่เหมือน browser403 เงียบ แม้ header จะถูกต้องใช้ curl_cffi แบบ impersonation หรือ browser จริง
HTTP/2 fingerprintingตรวจ SETTINGS ของ HTTP/2 และลำดับ HPACKบล็อกแบบเงียบcurl_cffi พูด HTTP/2 เหมือน Chrome
ตรวจสอบ Header (UA, Sec-Fetch-*)ชุด header ที่ต้องสอดคล้องกับ browser403 ตั้งแต่ request แรกใส่ Chrome header เต็มชุด รวม Sec-Fetch-Site/Mode/Dest/User, และ Referer ที่สมจริง
ความต่อเนื่องของ cookie/sessionติดตาม cf_clearance, RF_BROWSER_IDเจอ challenge เมื่อเข้าลิงก์ลึกแบบสด ๆใช้ Persistent Session; วอร์มหน้าแรกก่อน
Rate limit ระดับแอปจำกัดจำนวน request ต่อ IP429หน่วง 2–5 วินาทีแบบสุ่ม; ใช้ exponential backoff
ชื่อเสียง IP จาก datacenterบล็อก ASN ของศูนย์ข้อมูลที่รู้จักกันดี1020/403 ทันทีใช้ residential หรือ mobile proxy เท่านั้น
ตรวจจับ concurrencyหลาย request พร้อมกันจาก IP เดียวTurnstile โผล่ถี่ขึ้นแบบฉับพลันพร้อมกันต่อ IP ไม่เกิน 2 คำขอ

ค่าขีดจำกัดที่ใช้งานได้จริงจากการทดสอบของชุมชน:

  • จังหวะที่ปลอดภัย: 1 request ต่อ 2–3 วินาทีต่อ IP
  • ถ้าระยะยาวเกิน 20–30 req/นาที จาก datacenter IP เดียว จะเริ่มเจอ challenge ภายในไม่กี่นาที
  • soft rate-limit มักหายภายใน 5–15 นาทีเมื่อหยุดส่ง traffic
  • การแบน datacenter IP (AWS, GCP, Azure, OVH) อาจอยู่ได้นานตั้งแต่หลายชั่วโมงถึงหลายวัน

requests มาตรฐานของ Python (urllib3 + OpenSSL) สร้าง JA3 fingerprint ที่ไม่ตรงกับ browser ใด ๆ — และจึงโดนบล็อกแบบเงียบ ๆ แม้ header จะครบ วิธีที่วงการนิยมคือ curl_cffi พร้อม impersonate="chrome120" ซึ่งพูด TLS + HTTP/2 ได้ใกล้เคียง Chrome มาก

3 วิธีดึงข้อมูล Redfin ด้วย Python (และควรเลือกแบบไหน)

redfin_methods_dc0828acd4.png

ผมยังไม่เคยเจอบทความคู่แข่งที่เอาทั้ง 3 แนวทางมาเทียบกันแบบตรง ๆ เลย นี่คือตารางตัดสินใจ:

เกณฑ์HTML Parsing (BS4 + Selenium)Hidden API StingrayThunderbit (No-Code)
ความยากในการตั้งค่าปานกลาง (Python env + browser driver)สูง (ต้อง reverse-engineer endpoint)ต่ำ (ติดตั้ง Chrome extension)
ความเสี่ยงโดนบล็อกสูง (request แบบ DOM มองเห็นง่ายที่สุด)ปานกลาง (request สไตล์ API ดูธรรมชาติกว่า)ต่ำสุด (ใช้ browser session จริงของคุณ)
คุณภาพโครงสร้างข้อมูลปานกลาง (HTML ไม่เป็นโครงสร้าง ต้อง parse เอง)ดีเยี่ยม (JSON มีโครงสร้างอยู่แล้ว)สูง (AI ตรวจจับฟิลด์และชนิดข้อมูลให้)
ภาระดูแลรักษาสูง — layout เปลี่ยนที selector พังปานกลาง — endpoint อาจเปลี่ยนโดยไม่แจ้งต่ำสุด — AI ปรับตาม layout ได้
ความสามารถในการสเกลต่ำ–ปานกลาง (หลักร้อยพร้อม proxies)ปานกลาง–สูง (หลักพัน, request ดูสะอาดกว่า)ปานกลาง (50 หน้า/รอบผ่าน cloud scraping)
เหมาะที่สุดสำหรับนักพัฒนาที่ต้องการคุมทุกอย่างนักพัฒนาที่ต้องการ JSON สะอาด ๆคนไม่เขียนโค้ด, งานเร็ว, งานต่อเนื่องที่ไม่มีทีม dev รองรับ

เรื่องการดูแลรักษาสำคัญมาก Redfin เคยเปลี่ยน DOM ของการ์ดมาสองยุค — แบบเก่า (homecardV2Price) และแบบปัจจุบัน (span.bp-Homecard__Price--value) ประวัติ issue ใน GitHub ของชุมชนแสดงให้เห็นว่าการพังของ CSS selector เกิดขึ้นราวทุก 6–12 เดือน พอเกิดขึ้น scraper ที่พึ่ง BeautifulSoup จะพังข้ามคืน แต่ระบบตรวจจับฟิลด์ด้วย AI จะปรับตัวได้

ก่อนเริ่ม

  • ระดับความยาก: ปานกลาง (แนวทาง 1 และ 2), เริ่มต้น (แนวทาง 3)
  • เวลาที่ต้องใช้: ประมาณ 30 นาทีสำหรับแนวทาง 1 หรือ 2; ประมาณ 5 นาทีสำหรับแนวทาง 3
  • สิ่งที่ต้องมี:
    • Python 3.8+ พร้อม pip (แนวทาง 1 และ 2)
    • เบราว์เซอร์ Chrome (ทุกแนวทาง)
    • Thunderbit Chrome Extension (แนวทาง 3)
    • US residential proxies สำหรับงานสเกลใหญ่ (แนวทาง 1 และ 2)

ดึงข้อมูล Redfin ด้วย AI Get Started Free

แนวทางที่ 1: ดึงข้อมูล Redfin ด้วย Python แบบ parse HTML (BeautifulSoup + Selenium)

นี่คือเส้นทางแบบ "คุมได้ทั้งหมด" คุณเขียน selector เอง ดูแล browser เอง และจัดการ error เอง

เป็นวิธีที่ให้ความรู้ที่สุด และก็เปราะบางที่สุดด้วย

ขั้นตอนที่ 1: ตั้งค่า Python environment

สร้าง virtual environment และติดตั้งไลบรารีที่จำเป็น:

python -m venv redfin-scraper
source redfin-scraper/bin/activate  # บน Windows: redfin-scraper\Scripts\activate
pip install requests beautifulsoup4 selenium webdriver-manager pandas curl_cffi

curl_cffi สำคัญมาก — มันช่วยให้ HTTP request ของคุณเลียนแบบ TLS fingerprint ของ Chrome จริง ๆ แทน fingerprint มาตรฐานของ requests ใน Python ที่ Cloudflare มองเห็นแล้วบล็อกทันที

ขั้นตอนที่ 2: ตั้งค่า header ของเบราว์เซอร์และ session

ตรงนี้คือจุดที่มือใหม่ส่วนใหญ่พลาด คุณต้องใส่ Chrome header ให้ครบ รวมถึง Sec-Fetch-* headers ที่ Redfin/Cloudflare ตรวจสอบโดยตรง:

from curl_cffi import requests as curl_requests

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-User": "?1",
}

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# วอร์ม session — เก็บคุกกี้ cf_clearance และ RF_BROWSER_ID
session.get("https://www.redfin.com/")

ขั้นตอนวอร์ม session สำคัญมาก — ถ้าเข้า deep URL ของทรัพย์สินแบบสด ๆ (ไม่มีคุกกี้ก่อนหน้าและไม่มี Referer) จะโดน Cloudflare มองว่าเสี่ยงสูงขึ้น

เริ่มจากหน้าแรกเสมอ

ขั้นตอนที่ 3: ดึงผลการค้นหาของ Redfin

เมื่อ session พร้อมแล้ว คุณสามารถเรียกหน้าค้นหาของเมืองและ parse การ์ดประกาศได้ selector รุ่นปัจจุบัน (2024–2026):

import time
import random
from bs4 import BeautifulSoup

base_url = "https://www.redfin.com/city/17151/CA/San-Francisco"
listings = []

for page_num in range(1, 6):  # หน้า 1-5
    url = f"{base_url}/page-{page_num}" if page_num > 1 else base_url
    resp = session.get(url)

    if resp.status_code != 200:
        print(f"โดนบล็อกที่หน้า {page_num}: HTTP {resp.status_code}")
        break

    soup = BeautifulSoup(resp.text, "html.parser")
    cards = soup.select("[data-rf-test-id='property-card'], a.bp-Homecard")

    for card in cards:
        price_el = card.select_one("span.bp-Homecard__Price--value")
        addr_el = card.select_one("a.bp-Homecard__Address")
        stats = card.select("span.bp-Homecard__LockedStat--value")

        listing = {
            "price": price_el.text.strip() if price_el else None,
            "address": addr_el.text.strip() if addr_el else None,
            "beds": stats[0].text.strip() if len(stats) > 0 else None,
            "baths": stats[1].text.strip() if len(stats) > 1 else None,
            "sqft": stats[2].text.strip() if len(stats) > 2 else None,
            "url": "https://www.redfin.com" + addr_el["href"] if addr_el else None,
        }
        listings.append(listing)

    # หน่วงแบบสุ่ม 2–5 วินาที
    time.sleep(random.uniform(2, 5))

print(f"ดึงข้อมูลได้ {len(listings)} รายการ")

คุณควรจะเห็นลิสต์ dictionary ที่เพิ่มขึ้นเรื่อย ๆ โดยแต่ละรายการมีราคาบ้านใน San Francisco ที่อยู่ จำนวนห้องนอน/ห้องน้ำ/ตารางฟุต และลิงก์รายละเอียด ถ้าได้ cards เป็น 0 ให้เช็ก HTTP status code — ถ้าเป็น 403 แปลว่า Cloudflare จับได้ และคุณอาจต้องใช้ residential proxy

ขั้นตอนที่ 4: ดึงข้อมูลจากหน้ารายละเอียดแต่ละทรัพย์สิน

หน้าผลการค้นหาให้ข้อมูลพื้นฐาน ส่วนหน้ารายละเอียดให้ Redfin Estimate ปีที่สร้าง HOA ประวัติการขาย ข้อมูลเอเจนต์ และรูปภาพ หน้าเหล่านี้ต้อง render JavaScript จึงต้องสลับไปใช้ Selenium:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                     "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

for listing in listings[:10]:  # เติมข้อมูลให้ 10 รายการแรก
    driver.get(listing["url"])
    time.sleep(random.uniform(3, 6))  # รอให้ JS render

    try:
        estimate_el = driver.find_element(By.CSS_SELECTOR, "[data-rf-test-name='avmLdpPrice']")
        listing["redfin_estimate"] = estimate_el.text.strip()
    except:
        listing["redfin_estimate"] = None

    try:
        year_built = driver.find_element(By.XPATH, "//span[contains(text(),'Year Built')]/following-sibling::span")
        listing["year_built"] = year_built.text.strip()
    except:
        listing["year_built"] = None

driver.quit()

หลังทำขั้นตอนนี้ Listing 10 รายการแรกควรมีค่า Redfin Estimate และข้อมูลปีที่สร้างแล้ว XPath selectors มักทนต่อฟิลด์ amenity ที่ซ้อนกันได้ดีกว่า CSS แต่ก็ยังเปราะบาง — ถ้า DOM ถูกปรับใหม่เมื่อไร selector ก็พังอยู่ดี

ขั้นตอนที่ 5: รับมือการบล็อกและ error

เพิ่ม logic ลองใหม่พร้อม exponential backoff:

import time

def fetch_with_retry(session, url, max_retries=3):
    for attempt in range(max_retries):
        resp = session.get(url)
        if resp.status_code == 200:
            return resp
        elif resp.status_code in (403, 429, 503):
            wait = (2 ** attempt) + random.uniform(1, 3)
            print(f"โดนบล็อก ({resp.status_code}) จะลองใหม่ใน {wait:.1f} วินาที...")
            time.sleep(wait)
        else:
            print(f"สถานะไม่คาดคิด: {resp.status_code}")
            break
    return None

สัญญาณว่าโดนบล็อก ได้แก่ HTTP 403 พร้อม HTML ของ Cloudflare ใน body, HTTP 429 (rate limit ตรง ๆ), body ว่างเปล่า หรือมีคำว่า "Error 1020 Access Denied" อยู่ในเนื้อหา ถ้าเจอแบบนี้ซ้ำ ๆ ก็ถึงเวลาต้องเพิ่ม residential proxy หรือเปลี่ยนไปใช้แนวทาง API

แนวทางที่ 2: ดึงข้อมูล Redfin ด้วย Python ผ่าน Hidden Stingray API

นี่คือวิธีที่ผมชอบที่สุด ฝั่ง frontend ของ Redfin คุยกับ internal JSON API ที่ /stingray/api/home/details/* และ response ที่ได้กลับมาเป็น JSON ที่สะอาดและมีชนิดข้อมูลชัดเจน — ไม่ต้อง parse HTML เลย

วิธีหา endpoint ของ Hidden API ของ Redfin

เปิด Chrome DevTools → แท็บ Network → กรองด้วย Fetch/XHR → เข้าไปที่หน้าทรัพย์สินของ Redfin สักหน้า คุณจะเห็น request ไปยัง endpoint เช่น:

  • api/home/details/initialInfo — แกะ URL → propertyId, listingId
  • api/home/details/aboveTheFold — ราคา, ห้องนอน, ห้องน้ำ, ตารางฟุต, รูปภาพ, สถานะ, เอเจนต์, MLS#
  • api/home/details/belowTheFold — สิ่งอำนวยความสะดวก, HOA, ภาษี, ที่จอดรถ, ปีที่สร้าง, ขนาดที่ดิน, ประวัติ
  • api/home/details/avm — Redfin Estimate สำหรับทรัพย์ในตลาด
  • api/home/details/owner-estimate — Redfin Estimate สำหรับทรัพย์นอกตลาด
  • api/home/details/descriptiveParagraph — คำอธิบายเชิงการตลาด

สำหรับหน้ารายการเช่า rentalId (UUID 36 ตัวอักษร) จะถูกดึงจาก URL ของแท็ก <meta property="og:image">

ดึงข้อมูลทรัพย์สินผ่าน Stingray API

มีข้อควรรู้สำคัญ: response แบบ JSON ของ Stingray จะมี prefix เป็นสตริง literal {}&& เพื่อป้องกัน CSRF คุณต้องลบส่วนนี้ก่อน parse:

import json
from curl_cffi import requests as curl_requests

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# วอร์ม session
session.get("https://www.redfin.com/")

# ดึงหน้าทรัพย์สินเพื่อรับคุกกี้และ property ID
property_url = "https://www.redfin.com/CA/San-Francisco/123-Main-St-94102/home/12345678"
page_resp = session.get(property_url)

# เรียก Stingray API
api_url = "https://www.redfin.com/stingray/api/home/details/aboveTheFold?propertyId=12345678"
api_resp = session.get(api_url, headers={"Referer": property_url})

# ตัด prefix anti-CSRF ออก
payload = json.loads(api_resp.text.replace("{}&&", "", 1))

# ดึงข้อมูลแบบมีโครงสร้าง
listing_data = payload.get("payload", {})
print(json.dumps(listing_data, indent=2))

response จะมีฟิลด์ที่เป็นชนิดข้อมูลชัดเจน: ราคาเป็น integer, beds/baths เป็นตัวเลข, URL รูปภาพเป็น array, ข้อมูลเอเจนต์เป็น object ซ้อนกัน ไม่มีการ parse HTML ไม่มี CSS selectors และไม่ต้องเดา

ข้อดีและข้อจำกัดของแนวทาง Hidden API

ข้อดี:

  • JSON มีโครงสร้างพร้อมใช้ — สะอาดกว่า HTML parsing มาก
  • เร็วกว่าในแต่ละ request (payload เล็กกว่า ไม่ต้อง render)
  • ความเสี่ยงโดนบล็อกต่ำกว่า (request แบบ API ที่มี header ถูกต้องดูธรรมชาติกว่า)

ข้อจำกัด:

  • Endpoint อาจเปลี่ยนได้โดยไม่แจ้ง — ไม่มีเอกสารทางการ
  • robots.txt ห้าม /stingray/ สำหรับ user-agent แบบ wildcard อย่างชัดเจน
  • ต้อง reverse-engineer เพื่อหา endpoint ใหม่ ๆ
  • ยังต้องวอร์ม session และใส่ header ให้ถูกต้องเพื่อเลี่ยง Cloudflare

ทางเลือกแบบไม่ต้องเขียนโค้ด: ดึงข้อมูล Redfin ด้วย Thunderbit

ถ้าคุณต้องการข้อมูล Redfin แต่ไม่อยากดูแล Python scripts — หรือแค่อยากได้ผลลัพธ์ภายในห้านาที — เริ่มจากตรงนี้ก่อน เราสร้าง Thunderbit ขึ้นมาเพื่อสิ่งนี้โดยตรง: ดึงข้อมูลแบบมีโครงสร้างจากเว็บไซต์ใดก็ได้ โดยไม่ต้องเขียนโค้ด

ขั้นตอนที่ 1: ติดตั้ง Thunderbit แล้วเข้า Redfin

ติดตั้ง Thunderbit Chrome Extension จาก Chrome Web Store เปิด Redfin แล้วไปที่หน้าผลการค้นหา เช่น บ้านขายใน San Francisco

ขั้นตอนที่ 2: คลิก "AI Suggest Fields"

คลิกไอคอน Thunderbit ที่แถบเครื่องมือของเบราว์เซอร์ จากนั้นคลิก "AI Suggest Fields" AI จะอ่านหน้า Redfin แล้วเสนอคอลัมน์ให้อัตโนมัติ เช่น "Address," "Price," "Beds," "Baths," "SqFt," "Property Type," และ "Listing Photo" — พร้อมกำหนดชนิดข้อมูลให้ถูกต้องโดยอัตโนมัติ

คุณสามารถลบคอลัมน์ที่ไม่ต้องการ หรือเพิ่มคอลัมน์เองด้วยการคลิก "+ Add Column" แล้วพิมพ์สิ่งที่ต้องการเป็นภาษาธรรมดา เช่น "ชื่อเอเจนต์" หรือ "จำนวนวันในตลาด"

คุณจะเห็นตัวอย่างตารางที่ตั้งค่าไว้เรียบร้อย พร้อมเริ่มดึงข้อมูลได้ทันที

ขั้นตอนที่ 3: กด "Scrape" แล้วดูข้อมูลไหลเข้าตาราง

คลิกปุ่ม "Scrape" Thunderbit จะประมวลผลประกาศที่มองเห็นอยู่และเติมข้อมูลลงตารางให้ ถ้าเป็นผลลัพธ์หลายหน้า ระบบจะจัดการ pagination ให้เอง — ไม่ต้องเขียน loop

จากที่ผมทดสอบ ตาราง 50 แถวใช้เวลาประมาณ 45 วินาที ข้อมูลมีโครงสร้าง และ export ต่อได้ทันที

Thunderbit รับมือระบบป้องกันบอทของ Redfin ยังไง

เพราะ Thunderbit ทำงานใน browser ของคุณเอง จึงใช้คุกกี้ Session และ browser fingerprint ของ Redfin ที่คุณมีอยู่แล้ว Cloudflare เลยเห็นมันเป็นผู้ใช้จริงที่กำลังเข้าเว็บ Redfin — เพราะในทางเทคนิคมันก็คือการใช้งานจริง ไม่มี headless browser ไม่มี IP จาก datacenter ไม่มี TLS fingerprint แปลก ๆ สำหรับหน้าสาธารณะ Thunderbit mode แบบ cloud scraping สามารถประมวลผลได้ครั้งละ 50 หน้า

นั่นต่างจากการยิง requests จาก Python script บนเซิร์ฟเวอร์แบบคนละโลก

Session ของเบราว์เซอร์คุณได้รับความเชื่อถืออยู่แล้ว

ดึงข้อมูลหน้าย่อยของ Redfin ด้วย Thunderbit

หลังดึงผลการค้นหาแล้ว ให้คลิก "Scrape Subpages" เพื่อให้ AI เข้าไปยังลิงก์รายละเอียดของแต่ละทรัพย์และเติมข้อมูลเพิ่มลงในตาราง เช่น Redfin Estimate, ปีที่สร้าง, ค่า HOA, ข้อมูลเอเจนต์, รูปภาพทรัพย์สิน และประวัติการขาย

นี่เทียบเท่ากับ Selenium loop 40 บรรทัดในแนวทางที่ 1 — แต่ทำได้ด้วยการคลิกครั้งเดียวและไม่ต้องคอยดูแลโค้ดต่อ

เมื่อ Redfin เปลี่ยน DOM จาก homecardV2Price เป็น span.bp-Homecard__Price--value AI ก็ปรับตัวได้ แต่ selector ใน Python ของคุณไม่สามารถทำแบบนั้น

ดึงหน้าย่อยของ Redfin ด้วย AI Get Started Free

มากกว่า CSV: ส่งออกข้อมูล Redfin ไป Google Sheets, Airtable และ Notion

บทความสอนส่วนใหญ่หยุดแค่ df.to_csv() ซึ่งพอสำหรับการวิเคราะห์ครั้งเดียว แต่ถ้าคุณอยู่ในทีมอสังหาฯ คุณต้องการข้อมูลที่ใช้งานร่วมกันได้และอัปเดตต่อเนื่อง ไม่ใช่ไฟล์นิ่ง ๆ ที่เก็บฝุ่นอยู่บนเดสก์ท็อปของใครสักคน

การส่งออกด้วย Python (gspread + Airtable API)

Google Sheets ผ่าน gspread:

import gspread
import pandas as pd
from gspread_dataframe import set_with_dataframe

df = pd.DataFrame(listings)
gc = gspread.service_account(filename="service_account.json")
sh = gc.open("Redfin Listings")
ws = sh.worksheet("Sheet1")
ws.clear()
set_with_dataframe(ws, df, include_index=False, resize=True)

# แสดงรูปทรัพย์สินแบบ inline ด้วยสูตร IMAGE()
image_col = df.columns.get_loc("image_url") + 1
for row_idx, url in enumerate(df["image_url"], start=2):
    ws.update_cell(row_idx, image_col, f'=IMAGE("{url}")')

ข้อควรระวัง: Sheets มีลิมิตตายตัวที่ 10 ล้านเซลล์ต่อ spreadsheet และ API รองรับ 300 read + 300 write requests ต่อนาทีต่อโปรเจกต์ ถ้าเกินหลักไม่กี่สิบแถว ควรใช้ ws.batch_update() แทนการ loop อัปเดตทีละเซลล์

Airtable ผ่าน pyairtable:

การเปลี่ยนแปลงสำคัญปี 2024: Airtable ยกเลิก legacy API keys ตั้งแต่ 1 กุมภาพันธ์ 2024 ตอนนี้คุณต้องใช้ Personal Access Tokens (PATs) เท่านั้น — ถ้าบทความไหนยังใช้ api_key=... อยู่ แปลว่าโค้ดนั้นใช้ไม่ได้แล้ว

from pyairtable import Api

api = Api("patXXXXXXXXXXXXXX.yyyyyyyyyyyyyyyyyyyy")
table = api.table("appBaseId123", "Redfin Listings")

records = [
    {
        "Address": row["address"],
        "Price": row["price"],
        "Beds": row["beds"],
        "Photo": [{"url": row["image_url"]}],  # Airtable จะดึงไฟล์ไปโฮสต์ต่อ
    }
    for row in listings
]
created = table.batch_create(records, typecast=True)

Airtable จำกัดอัตราไว้ที่ 5 requests/วินาทีต่อหนึ่ง base และจะล็อก 30 วินาทีหากละเมิด ฟิลด์ attachment รองรับ payload แบบ [{"url": ...}] — เซิร์ฟเวอร์ของ Airtable จะไปดึง URL นั้นมา re-host บน CDN และสร้าง thumbnail ให้อัตโนมัติ

การส่งออกด้วย Thunderbit (คลิกครั้งเดียวไป Sheets, Airtable, Notion)

Thunderbit มีการ export แบบคลิกครั้งเดียวไปยัง Google Sheets, Airtable และ Notion แบบ native — และส่วนที่ผมชอบจริง ๆ คือรูปภาพทรัพย์สินจะถูกอัปโหลดและแสดงเป็น inline images ใน Notion และ Airtable ไม่ต้องใช้สูตร =IMAGE() แบบอ้อม ๆ และไม่ต้องลุ้นลิงก์ CDN เสีย คุณคลิก "Export to Airtable" แล้วทีมของคุณจะได้ฐานข้อมูลทรัพย์สินแบบเห็นภาพ พร้อม thumbnail ให้เปิดดูบนมือถือได้

สำหรับทีมอสังหาฯ ที่ต้องคัดกรองประกาศแบบเห็นภาพ นี่คือความต่างระหว่างเครื่องมือที่ใช้งานได้จริงกับกอง CSV ที่อ่านยาก

การ scraping Redfin ถูกกฎหมายไหม? robots.txt, ToS และแนวคดีว่าอย่างไร

ผมไม่ใช่ทนาย และนี่ไม่ใช่คำแนะนำทางกฎหมาย แต่จากประสบการณ์ในสาย data extraction มาหลายปี ผมบอกได้ว่า "มันถูกกฎหมายไหม" คือคำถามที่ทุกคนถาม และบทความสอนส่วนใหญ่ชอบเลี่ยง

robots.txt ของ Redfin

robots.txt ของ Redfin ค่อนข้างละเอียด จุดสำคัญคือ:

  • บอทที่ถูกบล็อกแบบชัดเจน: peer39_crawler/1.0, AmazonAdBot, FireCrawlAgent — Redfin ระบุชื่อบริการ scraping สาย LLM ที่คนใช้กันเยอะไว้ตรง ๆ
  • จุดที่ User-agent: * ห้ามเข้าถึง: /stingray/ (namespace ของ internal API ทั้งหมด), /myredfin/, /api/v1/rentals/, /api/v1/properties/, /owner-estimate/
  • ไม่มีคำสั่ง Crawl-delay: สำหรับ user agent ใด ๆ
  • ประกาศ sitemap กว่า 50 รายการ — sitemap คือวิธีไล่ URL ที่สะอาดและกระทบ WAF น้อยที่สุด

เงื่อนไขการใช้งานของ Redfin

ข้อ 2.3.5 ระบุว่า: "You may not automatedly crawl or query the Services for any purpose or by any means... unless you have received prior express written permission."

นี่เป็นข้อตกลงแบบ browsewrap — คือการยอมรับจากการใช้งานต่อเนื่อง ไม่ใช่ clickwrap ศาลสหรัฐฯ มักลังเลที่จะบังคับใช้ browsewrap กับผู้ใช้ที่ไม่ได้รับแจ้งจริง ๆ (ดู Nguyen v. Barnes & Noble, 9th Cir. 2014)

แนวคำพิพากษาที่เกี่ยวข้องแบบย่อ

  • Van Buren v. United States (ศาลสูงสุดสหรัฐฯ, 2021): บทบัญญัติ "exceeds authorized access" ใน CFAA ใช้การทดสอบแบบ "gate เปิดหรือปิด" การเปิดประตูที่มีอยู่แล้วเพื่อจุดประสงค์ที่ไม่พึงประสงค์ ไม่ใช่การแฮ็กตามกฎหมายอาญาของรัฐบาลกลาง
  • hiQ Labs v. LinkedIn (9th Cir., 2022): การ scraping ข้อมูลสาธารณะไม่ถือเป็นการละเมิด CFAA แต่ hiQ สุดท้ายยอมจ่าย 500,000 ดอลลาร์ในการยอมความในประเด็น breach-of-contract เพราะ hiQ เคยสมัครบัญชี LinkedIn และกด "I agree"
  • Meta Platforms v. Bright Data (N.D. Cal., ม.ค. 2024): ศาลมีคำพิพากษาแบบ summary judgment ให้ Bright Data — การ scraping ข้อมูลสาธารณะในสถานะที่ไม่ได้ล็อกอินไม่ทำให้ Bright Data เป็น "user" ที่ต้องผูกพันตาม ToS ของ Meta
  • X Corp. v. Bright Data (N.D. Cal., พ.ค. 2024): ผู้พิพากษา Alsup ยกฟ้องข้อเรียกร้องของ X โดยเห็นว่าคำร้องตามกฎหมายรัฐที่พยายามควบคุมการคัดลอกเนื้อหาสาธารณะถูกกฎหมายลิขสิทธิ์รัฐบาลกลางครอบทับ

คำแนะนำเชิงปฏิบัติ

  • ดึงเฉพาะข้อมูลที่เข้าถึงได้แบบสาธารณะ — อย่าสมัครบัญชีแล้วค่อย scrape (เพราะจะสร้างความเสี่ยงเรื่อง clickwrap contract)
  • เคารพ rate limit — ปริมาณที่แรงเกินไปอาจถูกยกไปเป็นข้อเรียกร้องเรื่อง trespass-to-chattels ได้
  • อย่านำข้อมูลดิบหรือรูปภาพไปเผยแพร่ซ้ำในวงกว้าง — คดี CoStar v. Zillow (ยื่นฟ้องกรกฎาคม 2025, ค่าเสียหายอาจเกิน 1 พันล้านดอลลาร์) เป็นเครื่องเตือนว่าเรื่องลิขสิทธิ์ภาพไม่ใช่เรื่องเล็ก
  • แนวทางของ Thunderbit ที่ทำงานผ่าน browser ของคุณเอง — ใช้ session ที่คุณล็อกอินอยู่แล้ว — ใกล้เคียงกับ "การเปิดเว็บด้วยมือในความเร็วเครื่องจักร" มากกว่า bot บน datacenter แบบ headless ซึ่งเป็นท่าทีที่ป้องกันตัวได้ดีกว่าถ้ายังไม่ถึงขั้นใช้ API ที่มีใบอนุญาต

เคล็ดลับและข้อผิดพลาดที่พบบ่อย

นี่คือบทเรียนที่ได้มาจากการสร้างเครื่องมือดึงข้อมูลและเห็นผู้ใช้หลายพันคน scrape เว็บไซต์อสังหาฯ:

  • วอร์ม session ทุกครั้ง ก่อนเข้า deep URL ให้เรียก redfin.com/ ก่อนเสมอ การเข้า deep URL แบบสด ๆ คือสาเหตุอันดับ 1 ที่ทำให้โดน Cloudflare challenge
  • สลับ User-Agent ให้สมจริง อย่าใช้ค่าเดียวตลอด ควรสลับระหว่าง UA ของ Chrome/Firefox รุ่นปัจจุบัน 5–10 แบบ แต่ก็อย่าสลับถี่เกินไป (UA ใหม่ทุก request ดูน่าสงสัย)
  • ลบข้อมูลซ้ำตาม Property ID pagination ของ Redfin บางครั้งซ้อนกัน แยก /home/{id} จาก URL ของแต่ละประกาศแล้วค่อย deduplicate ก่อน enrichment
  • ถ้าเลี่ยงได้ อย่า scrape ตอนชั่วโมงพีก จากประสบการณ์ของผม ช่วงดึกหรือเช้าตรู่ตามเวลา US จะเจอการตรวจ WAF น้อยกว่า
  • ถ้าได้ 429 ให้ถอยแบบทวีคูณ อย่าลองใหม่ทันที — นั่นคือทางลัดจาก soft rate limit ไปสู่การแบน IP แบบถาวร
  • ถ้างานใหญ่ (1,000+ หน้า) ให้กันงบสำหรับ residential proxy IP จาก datacenter (AWS, GCP, Azure, OVH) จะถูกบล็อกโดยระบบ reputation ของ ASN ของ Cloudflare คุณจะเจอ Error 1020 เกือบทันที

เลือกวิธีที่เหมาะกับการดึงข้อมูล Redfin

แล้วควรเลือกแนวทางไหนดี? ขึ้นอยู่กับว่าคุณเป็นใคร และต้องการอะไร

HTML Parsing (BeautifulSoup + Selenium): เหมาะที่สุดสำหรับนักพัฒนาที่อยากคุมทุกอย่างเอง รับได้กับการดูแล CSS selector และไม่ติดใจหากต้องสร้างใหม่เมื่อ Redfin เปลี่ยน DOM คาดว่าจะต้องกลับมาแก้โค้ดทุก 6–12 เดือน

Hidden Stingray API: เหมาะที่สุดสำหรับนักพัฒนาที่ต้องการ JSON ที่สะอาดและมีโครงสร้าง พร้อมรับมือกับการ reverse-engineer endpoint ที่ไม่ได้เอกสารไว้ ภาระดูแลรักษาต่ำกว่า HTML parsing แต่ endpoint อาจเปลี่ยนโดยไม่แจ้ง และอย่าลืมว่า /stingray/ ถูกห้ามไว้ใน robots.txt อย่างชัดเจน

Thunderbit (No-Code): เหมาะที่สุดสำหรับคนไม่เขียนโค้ด งานเร็ว และทีมที่ต้องใช้ข้อมูล Redfin ต่อเนื่องโดยไม่มีทรัพยากร developer AI ปรับตาม layout ได้ การ scrape หน้าย่อยช่วยเติมข้อมูลด้วยการคลิกเดียว และมีการ export ไป Google Sheets, Airtable หรือ Notion ในตัว ถ้าคุณเป็นทีมอสังหาฯ ที่อยากได้ฐานข้อมูลทรัพย์สินที่ใช้งานต่อได้จริง — ไม่ใช่แค่กอง CSV ครั้งเดียวจบ — นี่คือทางที่ราบที่สุด

ไม่ว่าคุณจะเลือกทางไหน: ทำความเข้าใจระบบป้องกันบอทของ Redfin ก่อนเริ่ม รู้ว่าคุณต้องการฟิลด์อะไร เลือกรูปแบบ export ให้เข้ากับ workflow ของทีม และอยู่บนฝั่งที่ถูกต้องของ แนวทางทางกฎหมาย

พร้อมลองทาง no-code แล้วหรือยัง? แผนฟรีของ Thunderbit ให้คุณทดลองดึงข้อมูลจาก Redfin และเห็นผลได้ภายในไม่กี่นาที ส่วนแนวทาง Python โค้ดตัวอย่างด้านบนคือจุดเริ่มต้นที่ใช้งานได้จริง — แค่เติม proxy และความอดทนเข้าไป

ลองใช้ Thunderbit สำหรับข้อมูล Redfin ระยะยาว

คำถามที่พบบ่อย

Redfin มี public API ไหม?

ไม่มี Redfin ไม่มี public API อย่างเป็นทางการ Hidden Stingray API (/stingray/api/home/details/*) ให้ JSON ที่มีโครงสร้างและถูกใช้โดย frontend ของ Redfin เอง แต่ไม่เป็นทางการ ไม่มีเอกสาร และอาจเปลี่ยนได้โดยไม่แจ้ง พร้อมทั้งถูกห้ามไว้ใน robots.txt ของ Redfin อย่างชัดเจน wrapper แบบโอเพนซอร์สอย่าง reteps/redfin บน PyPI ช่วยให้เข้าถึงด้วย Python ได้ แต่ควรใช้อย่างเข้าใจความเสี่ยง

ดึงข้อมูล Redfin โดยไม่ใช้ Python ได้ไหม?

ได้ Thunderbit คือ Chrome extension ที่ใช้ AI และอาศัย session ของเบราว์เซอร์คุณเพื่อความทนทานต่อระบบป้องกันบอท — แค่ติดตั้ง เข้า Redfin คลิก "AI Suggest Fields" แล้ว export ไป Excel, Google Sheets, Airtable หรือ Notion นอกจากนี้ยังมีเครื่องมือ scraping แบบ no-code และผู้ให้บริการ dataset สำเร็จรูปในตลาดอีกหลายรายถ้าอยากสำรวจตัวเลือกอื่น

Redfin เปลี่ยน layout เว็บไซต์บ่อยแค่ไหน?

จากประวัติ issue บน GitHub ของชุมชน พบว่า selector ที่พังเพราะเปลี่ยน CSS เกิดขึ้นราวทุก 6–12 เดือน Redfin เคยใช้ DOM ของการ์ดสองยุค — แบบเก่า (homecardV2Price, homeAddressV2) และแบบปัจจุบัน (bp-Homecard__Price--value, bp-Homecard__Address) scraper ที่ดีมักลองทั้งสองชุดตามลำดับ

เครื่องมือที่ใช้ AI อย่าง Thunderbit ปรับตัวอัตโนมัติ เพราะตรวจจับฟิลด์จากเนื้อหา ไม่ได้ยึดติดกับ CSS selector

proxy แบบไหนเหมาะที่สุดสำหรับการ scrape Redfin?

US residential proxy เหมาะที่สุดสำหรับงานสเกลใหญ่ — benchmark ของชุมชนให้ success rate ราว 80% ส่วน datacenter proxy มักเจอ Cloudflare Error 1020 แทบจะทันที ช่วง IP ของ AWS, GCP, Azure และ OVH มักถูก blacklist ไปแล้ว Mobile proxy มีอัตราความสำเร็จสูงสุด แต่ราคาแพงกว่าประมาณ 5–10 เท่า

สำหรับงานส่วนตัวขนาดเล็ก (<100 หน้า) การใส่ header ให้ถูกต้อง + ใช้ curl_cffi แบบ impersonation + หน่วงเวลา 2–5 วินาที อาจใช้ได้โดยไม่ต้องมี proxy เลย

ดึงข้อมูลทรัพย์สินที่ขายแล้วหรืออยู่นอกตลาดจาก Redfin ได้ไหม?

ได้ ข้อมูลทรัพย์สินที่ขายแล้วและ Redfin Estimate สำหรับทรัพย์นอกตลาด (ค่าคลาดเคลื่อนมัธยฐาน 7.52%) มีอยู่ในหน้ารายละเอียดและดึงได้ด้วยแนวทางเดียวกัน ฟิลด์จะแตกต่างจากประกาศที่ยัง active: หน้านอกตลาดจะแสดงราคาขาย วันที่ขาย ประวัติทรัพย์สิน และ endpoint สำหรับ owner-estimate แต่จะไม่มี list price ปัจจุบัน จำนวนวันในตลาด และข้อมูล open house ส่วน endpoint ของ Stingray สำหรับการประเมินนอกตลาดคือ api/home/details/owner-estimate แทน api/home/details/avm

ลองใช้ Thunderbit สำหรับดึงข้อมูล Redfin Get Started Free

อ่านเพิ่มเติม

Shuai Guan
Shuai Guan
CEO แห่ง Thunderbit | ผู้เชี่ยวชาญด้านการทำงานอัตโนมัติของข้อมูลด้วย AI Shuai Guan เป็น CEO ของ Thunderbit และเป็นศิษย์เก่าคณะวิศวกรรมศาสตร์ มหาวิทยาลัยมิชิแกน ด้วยประสบการณ์เกือบสิบปีในสายเทคโนโลยีและสถาปัตยกรรม SaaS เขาเชี่ยวชาญในการเปลี่ยนโมเดล AI ที่ซับซ้อนให้กลายเป็นเครื่องมือดึงข้อมูลแบบไม่ต้องเขียนโค้ดที่ใช้งานได้จริง บนบล็อกนี้ เขาแบ่งปันมุมมองตรงไปตรงมาและผ่านการใช้งานจริงเกี่ยวกับการทำเว็บสแครปปิงและกลยุทธ์การทำงานอัตโนมัติ เพื่อช่วยให้คุณสร้างเวิร์กโฟลว์ที่ฉลาดขึ้นและขับเคลื่อนด้วยข้อมูลได้ดียิ่งขึ้น เมื่อไม่ได้กำลังปรับแต่งเวิร์กโฟลว์ข้อมูล เขาก็ยังใช้สายตาที่พิถีพิถันแบบเดียวกันกับงานอดิเรกด้านการถ่ายภาพ
สารบัญ

ดึงข้อมูลหน้าเว็บได้ด้วยการบอกแค่คำสั่ง

บอกสิ่งที่ต้องการเป็นภาษาอังกฤษง่าย ๆ หรือจะไม่ต้องบอกอะไรเลยก็ได้

ลอง Thunderbit ฟรี
ดึงข้อมูลด้วย AI
โอนข้อมูลไปยัง Google Sheets, Airtable หรือ Notion ได้อย่างง่ายดาย
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week