Ngiêm cấm sử đụng PROXY và VPS vào mục đích trái pháp luật bạn sẽ phải chịu toàn bộ trách nhiệm trước pháp luật khi sử dụng dịch vụ của chúng tôi tks!
Crawl Zillow bằng Python: quyền dữ liệu và thay đổi giá

Crawl Zillow bằng Python: quyền dữ liệu, schema và thay đổi giá

Chuyên viên Kỹ thuật ProxyVN 04-23-2026 Đang tính... phút đọc

Crawl Zillow bằng Python là yêu cầu hay gặp của dân dữ liệu bất động sản Mỹ, nhưng việc đầu tiên là kiểm tra quyền thu thập chứ không phải mở trình soạn code. Zillow có bộ dữ liệu nghiên cứu tải công khai và có kênh dữ liệu cấp phép. Bài này, ProxyVN hướng dẫn dựng schema tin nhà đất, theo dõi thay đổi giá và đọc dữ liệu Zillow Research bằng Python.

Mục tiêu và phạm vi của crawl Zillow bằng Python

Người tìm cách lấy dữ liệu Zillow thường muốn trả lời một trong hai loại câu hỏi. Loại thứ nhất ở cấp thị trường: giá nhà điển hình ở một vùng thay đổi thế nào theo tháng. Loại thứ hai ở cấp từng căn: một tin rao đã giảm giá mấy lần, mỗi lần bao nhiêu. Hai loại câu hỏi cần hai nguồn dữ liệu khác nhau.

Cấp thị trường và cấp tin rao

Câu hỏi cấp thị trường cần chuỗi thời gian theo vùng, ví dụ theo thành phố, quận hạt hay mã ZIP. Dữ liệu này đã được tổng hợp, không chứa thông tin của từng căn nhà hay từng chủ sở hữu. Đây là loại dữ liệu dễ xin quyền và dễ dùng nhất.

Câu hỏi cấp tin rao cần từng bản ghi: địa chỉ, giá rao, số phòng, diện tích, trạng thái và lịch sử giá. Dữ liệu này đến từ hệ thống niêm yết của môi giới, gọi là MLS, và được cấp phép theo quy định riêng. Trang hiển thị của Zillow là nơi trình bày lại dữ liệu đó, không phải nơi cấp quyền sử dụng lại.

Kết quả bài này mang lại

Sau bài, anh em có hai thứ. Thứ nhất là kịch bản đọc tệp chỉ số giá nhà ZHVI do Zillow công bố, đổi từ dạng bảng rộng sang dạng dài và lưu SQLite. Thứ hai là schema và code theo dõi thay đổi giá cho tin rao, chạy được với dữ liệu mẫu và sẵn sàng nhận dữ liệu từ nguồn cấp phép.

Bài không hướng dẫn đọc trang Zillow hàng loạt, không vượt hệ thống chống bot và không thu thập thông tin chủ nhà. Với bất động sản, dữ liệu tổng hợp công khai thường trả lời được nhiều câu hỏi hơn anh em nghĩ. Tóm lại, crawl Zillow bằng Python cần bắt đầu bằng việc tách câu hỏi cấp thị trường khỏi câu hỏi cấp tin rao.

Kiểm tra quyền thu thập khi crawl Zillow bằng Python

Zillow là website bất động sản lớn với hệ thống chống truy cập tự động rõ ràng. Trước khi viết bất kỳ kịch bản nào chạm tới trang của họ, anh em cần đọc điều khoản và tìm kênh dữ liệu chính thức. Phần này đi qua ba bước kiểm tra đó.

Đọc điều khoản trước khi viết code

Đọc điều khoản trước khi viết code

Điều khoản sử dụng

Khi ProxyVN mở trang điều khoản sử dụng của Zillow bằng trình duyệt tự động ngày 23/10/2026, trang trả về thông báo truy cập bị từ chối. Chi tiết này tự nó đã là một thông tin: Zillow chủ động chặn truy cập tự động, kể cả với trang văn bản pháp lý. Anh em nên mở điều khoản bằng trình duyệt thông thường và đọc kỹ phần quy định về thu thập dữ liệu, sử dụng thương mại và tái phân phối.

Các website bất động sản lớn ở Mỹ thường cấm thu thập tự động khi không có văn bản cho phép. Ví dụ, điều khoản sử dụng của Redfin ghi rõ không được tự động crawl hay truy vấn dịch vụ cho bất kỳ mục đích nào nếu không có sự cho phép trước bằng văn bản. Anh em nên giả định mức hạn chế tương tự với Zillow cho tới khi đọc được điều khoản của họ.

Nguồn công khai: Zillow Research

Trang dữ liệu của Zillow Research cho phép tải các chỉ số nhà ở để dùng trong phân tích riêng. Danh sách gồm Zillow Home Value Index, chỉ số tiền thuê ZORI, dự báo, lượng hàng tồn, số giao dịch và nhiều chỉ số khác. Dữ liệu chia theo cấp vùng như quốc gia, vùng đô thị, bang, quận hạt, thành phố và mã ZIP.

Theo mô tả trên trang, ZHVI phản ánh giá trị điển hình của nhà trong khoảng phân vị 35 tới 65 của một vùng, có bản làm mượt điều chỉnh mùa vụ và bản thô. Trang cũng ghi rằng từ đợt công bố tháng 1/2023, toàn bộ chuỗi ZHVI được nâng cấp theo mô hình Zestimate mới. Chi tiết này quan trọng khi anh em so sánh với số liệu tải về trước năm 2023.

Dữ liệu cấp tin rao qua kênh cấp phép

Dữ liệu từng căn hợp lệ nhất đến từ MLS nơi tin được niêm yết, thông qua nhà cung cấp dữ liệu được cấp phép hoặc thông qua tư cách thành viên của môi giới. Nhóm Zillow cũng có dịch vụ dữ liệu cho đối tác bất động sản, đòi hỏi đăng ký và được duyệt. Mỗi kênh có điều khoản riêng về lưu trữ, hiển thị và ghi nguồn.

Nếu anh em là môi giới hoặc làm việc cho môi giới, dữ liệu tin rao của chính văn phòng mình cũng là nguồn hợp lệ. Schema trong bài được thiết kế để nhận dữ liệu từ những kênh này, chứ không phải từ trang hiển thị công khai.

Kết luận của phần này: crawl Zillow bằng Python một cách bền vững là tải dữ liệu nghiên cứu công khai cho câu hỏi thị trường và dùng kênh cấp phép cho câu hỏi từng căn. Hai đường này đủ cho phần lớn dự án phân tích.

Schema tin bất động sản khi crawl Zillow bằng Python

Dữ liệu nhà đất có đặc thù: một căn nhà tồn tại lâu, nhưng tin rao về nó xuất hiện, đổi giá, tạm dừng và biến mất nhiều lần. Schema phải tách căn nhà khỏi tin rao và tách tin rao khỏi các sự kiện giá. Gộp ba thứ vào một bảng là nguồn gốc của phần lớn lỗi phân tích.

Ba bảng cho ba thực thể

Bảng properties lưu căn nhà với khoá tạo từ địa chỉ đã chuẩn hoá. Bảng listings lưu từng lần rao bán, khoá là cặp nguồn và mã tin gốc. Bảng price_events lưu từng sự kiện giá của một tin: đăng bán, giảm giá, tăng giá, chờ giao dịch, đã bán, rút tin.

  • properties: property_key, address_line, city, state, zip, beds, baths, sqft, year_built.
  • listings: listing_key, property_key, source, source_id, list_date, status, url.
  • price_events: listing_key, event_date, event_type, price, prev_price, change_abs, change_pct.

Bảng properties không có tên chủ nhà, số điện thoại hay email môi giới. Tên môi giới niêm yết đôi khi bắt buộc hiển thị theo quy định MLS, nhưng đó là phần trình bày, không cần lưu vào kho phân tích.

Chuẩn hoá địa chỉ làm khoá

Cùng một căn có thể được ghi "123 Main St Apt 4" ở nguồn này và "123 MAIN STREET #4" ở nguồn khác. Khoá căn nhà cần quy hai cách ghi về một. Code bên dưới làm việc này ở mức cơ bản: chữ thường, bỏ dấu câu, đổi các từ viết tắt phổ biến và chuẩn hoá ký hiệu căn hộ.

Chuẩn hoá địa chỉ ở mức sản xuất là bài toán lớn, thường dùng dịch vụ chuẩn hoá chuyên dụng. Mức cơ bản trong bài đủ cho dữ liệu từ một hoặc hai nguồn có định dạng gần nhau. Khi số nguồn tăng, anh em nên đo tỷ lệ khớp sai trước khi tin vào kết quả gộp.

Sự kiện giá thay vì cột giá

Lỗi hay gặp là lưu giá như một cột của tin rao và ghi đè mỗi lần cập nhật. Cách này mất toàn bộ lịch sử. Bảng price_events lưu mỗi lần giá đổi thành một dòng, kèm giá trước đó và mức thay đổi tính bằng tiền lẫn phần trăm.

Với bảng sự kiện, câu hỏi như "tin này giảm giá mấy lần" hay "trung bình mất bao nhiêu ngày từ lúc đăng tới lần giảm đầu" trở thành truy vấn SQL đơn giản. Tóm lại, schema ba bảng với sự kiện giá riêng là nền tảng để phân tích thay đổi giá một cách đúng.

Chuẩn bị môi trường cho crawl Zillow bằng Python

Lab chỉ dùng thư viện chuẩn của Python: module csv để đọc tệp, sqlite3 để lưu, statistics để tính trung vị. Không cần thư viện phân tích HTML vì bài không đọc trang web. Phần tải tệp dùng Requests khi chạy thật.

Cài đặt tối thiểu

Môi trường ảo vẫn nên có để cố định phiên bản Requests. Khi ProxyVN dựng lab, phiên bản là Requests 2.34.2 trên Python 3.12.10.

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install requests
python -m pip freeze > requirements-lock.txt

Với tệp ZHVI cấp vùng đô thị, kích thước vừa phải, đọc bằng module csv trên máy cá nhân không gặp vấn đề. Với tệp cấp mã ZIP, số dòng lớn hơn nhiều, anh em có thể chuyển sang pandas hoặc đọc theo luồng như code bên dưới.

Cấu trúc tệp ZHVI

Khi ProxyVN tải tệp ZHVI vùng đô thị bản làm mượt ngày 23/10/2026, dòng tiêu đề có năm cột định danh: RegionID, SizeRank, RegionName, RegionType, StateName. Sau đó là một cột cho mỗi tháng, tên cột là ngày cuối tháng, từ 2000-01-31 tới 2026-09-30. Dòng đầu tiên là United States với RegionType bằng country.

Đây là định dạng bảng rộng: mỗi vùng một dòng, mỗi tháng một cột. Định dạng này tiện để mở bằng Excel nhưng bất tiện cho truy vấn và nối bảng. Bước đầu tiên của kịch bản là đổi sang dạng dài, mỗi dòng là một cặp vùng và tháng.

Dữ liệu mẫu

Lab dùng một đoạn CSV nhỏ cùng cấu trúc với tệp thật nhưng số liệu là giả lập, không phải số liệu Zillow công bố. Bộ mẫu tin rao cũng giả lập, gồm một căn có ba lần đổi giá và một căn rao lại sau khi rút tin.

Tóm lại, môi trường cho bài này rất gọn. Phần quan trọng là hiểu cấu trúc tệp trước khi viết code đọc nó.

Đọc Zillow Research khi crawl Zillow bằng Python

Phần này đọc tệp ZHVI, đổi sang dạng dài, lưu SQLite và tính mức thay đổi theo năm. Đây là ví dụ triển khai do ProxyVN viết, đã chạy với đoạn CSV mẫu trong lab.

Từ bảng rộng sang bảng dài

Từ bảng rộng sang bảng dài

Đổi bảng rộng sang bảng dài

Hàm zhvi_long đọc từng dòng, giữ năm cột định danh và tách mỗi cột tháng thành một bản ghi. Ô trống được bỏ qua vì nhiều vùng nhỏ chỉ có dữ liệu từ một năm nào đó trở đi.

import csv
import io
import re
import sqlite3
import statistics
from datetime import date
 
ID_COLS = ["RegionID", "SizeRank", "RegionName", "RegionType", "StateName"]
 
ZHVI_SAMPLE = """RegionID,SizeRank,RegionName,RegionType,StateName,2025-07-31,2025-08-31,2025-09-30,2026-07-31,2026-08-31,2026-09-30
900001,0,United States,country,,350000,351000,351500,358000,358500,359000
900002,1,Demo Metro A,msa,TX,300000,301500,302000,295000,294000,293500
900003,2,Demo Metro B,msa,FL,410000,,412000,430000,431000,433000
"""
 
def zhvi_long(fileobj):
    reader = csv.DictReader(fileobj)
    months = [c for c in reader.fieldnames if re.fullmatch(r"\d{4}-\d{2}-\d{2}", c)]
    for row in reader:
        for m in months:
            v = row.get(m)
            if v:
                yield {"region_id": int(row["RegionID"]), "region": row["RegionName"],
                       "region_type": row["RegionType"], "state": row["StateName"],
                       "month": m[:7], "zhvi": float(v)}
 
rows = list(zhvi_long(io.StringIO(ZHVI_SAMPLE)))
print(len(rows), rows[0])

Cột tháng được nhận diện bằng biểu thức chính quy thay vì vị trí, nên khi Zillow thêm cột định danh mới, code vẫn chạy. Tháng được cắt còn dạng năm-tháng vì ngày cuối tháng không mang thông tin thêm. Bộ mẫu cho 17 bản ghi, ít hơn 18 vì một ô trống của Demo Metro B bị bỏ qua.

Lưu và tính thay đổi theo năm

Bảng zhvi có khoá chính là cặp vùng và tháng. Tải lại tệp mới mỗi tháng chỉ cần chèn đè, các tháng cũ được cập nhật nếu Zillow điều chỉnh lại chuỗi số liệu, điều trang dữ liệu có nhắc tới khi nâng cấp phương pháp.

def save_zhvi(con, rows):
    con.execute("""CREATE TABLE IF NOT EXISTS zhvi (region_id INTEGER, region TEXT,
        region_type TEXT, state TEXT, month TEXT, zhvi REAL, PRIMARY KEY (region_id, month))""")
    con.executemany("INSERT OR REPLACE INTO zhvi VALUES (:region_id, :region, :region_type, "
                    ":state, :month, :zhvi)", rows)
    con.commit()
 
def yoy(con, month):
    prev = f"{int(month[:4]) - 1}{month[4:]}"
    return con.execute("""SELECT a.region, a.zhvi, b.zhvi, ROUND(100.0 * (a.zhvi - b.zhvi) / b.zhvi, 2)
        FROM zhvi a JOIN zhvi b ON a.region_id = b.region_id
        WHERE a.month = ? AND b.month = ? ORDER BY 4 DESC""", (month, prev)).fetchall()
 
con = sqlite3.connect(":memory:")
save_zhvi(con, rows)
for r in yoy(con, "2026-09"):
    print(r)

Kết quả với bộ mẫu: Demo Metro B tăng 5,1%, United States tăng 2,13%, Demo Metro A giảm 2,81% so với cùng kỳ. Các con số này chỉ minh hoạ cách tính, không phản ánh thị trường thật.

Tải tệp thật

Khi chạy thật, anh em lấy đường dẫn tệp từ trang Zillow Research, tải một lần mỗi tháng sau ngày công bố. Hàm dưới tải theo luồng như hướng dẫn body content workflow của Requests và đọc thẳng vào zhvi_long mà không cần lưu tệp trung gian.

import requests
 
def download_zhvi(url, session=None):
    s = session or requests.Session()
    with s.get(url, stream=True, timeout=(10, 120),
               headers={"User-Agent": "housing-research-lab/0.1"}) as r:
        r.raise_for_status()
        lines = (line.decode("utf-8") for line in r.iter_lines() if line)
        return list(zhvi_long(lines))

Đường dẫn tệp có thể đổi khi Zillow tổ chức lại trang dữ liệu, nên anh em lưu đường dẫn trong tệp cấu hình thay vì viết cứng trong code. Tóm lại, Zillow Research cung cấp sẵn câu trả lời cho câu hỏi cấp thị trường, chỉ cần đổi định dạng và lưu đúng khoá.

Theo dõi thay đổi giá khi crawl Zillow bằng Python

Với dữ liệu tin rao từ kênh cấp phép, mỗi lần cập nhật anh em nhận trạng thái hiện tại của tin. Nhiệm vụ của kịch bản là biến chuỗi trạng thái thành chuỗi sự kiện giá. Phần này dựng code làm việc đó.

Khoá căn nhà và khoá tin rao

Hai hàm đầu tạo khoá. Khoá căn nhà dựa trên địa chỉ chuẩn hoá cùng mã ZIP. Khoá tin rao dựa trên nguồn và mã tin gốc, vì một căn có thể được rao nhiều lần với mã khác nhau.

import hashlib
 
ABBR = {"street": "st", "avenue": "ave", "road": "rd", "drive": "dr", "boulevard": "blvd",
        "lane": "ln", "court": "ct", "apartment": "apt", "unit": "apt", "suite": "ste"}
 
def norm_address(line):
    s = re.sub(r"[^\w\s#]", " ", line.lower())
    s = s.replace("#", " apt ")
    words = [ABBR.get(w, w) for w in s.split()]
    return " ".join(words)
 
def property_key(line, zip_code):
    raw = f"{norm_address(line)}|{str(zip_code)[:5]}"
    return hashlib.sha1(raw.encode("utf-8")).hexdigest()[:16]
 
print(norm_address("123 Main Street #4"), "|", norm_address("123 MAIN ST, Apt 4"))
print(property_key("123 Main Street #4", "78701") == property_key("123 MAIN ST, Apt 4", "78701-1234"))

Hai cách ghi địa chỉ trong ví dụ cùng cho chuỗi "123 main st apt 4" và cùng khoá. Mã ZIP chỉ lấy năm chữ số đầu để bỏ phần mở rộng ZIP+4.

Từ chuỗi bản ghi tới sự kiện giá

Hàm price_events nhận danh sách bản ghi của một tin theo thứ tự thời gian, mỗi bản ghi gồm ngày, trạng thái và giá. Sự kiện được sinh ra khi giá đổi hoặc trạng thái đổi. Mức thay đổi tính so với giá rao gần nhất trước đó.

def price_events(snapshots):
    events, prev_price, prev_status = [], None, None
    for snap in sorted(snapshots, key=lambda s: s["date"]):
        price, status = snap.get("price"), snap["status"]
        if prev_status is None:
            etype = "listed"
        elif status != prev_status:
            etype = {"pending": "pending", "sold": "sold", "off_market": "withdrawn",
                     "for_sale": "relisted"}.get(status, status)
        elif price != prev_price:
            etype = "price_cut" if price < prev_price else "price_increase"
        else:
            continue
        change = (price - prev_price) if (price is not None and prev_price) else None
        pct = round(100.0 * change / prev_price, 2) if change is not None else None
        events.append({"date": snap["date"], "type": etype, "price": price,
                       "prev_price": prev_price, "change_abs": change, "change_pct": pct})
        prev_price = price if price is not None else prev_price
        prev_status = status
    return events
 
SNAPS = [
    {"date": "2026-07-01", "status": "for_sale", "price": 525000},
    {"date": "2026-07-08", "status": "for_sale", "price": 525000},
    {"date": "2026-07-22", "status": "for_sale", "price": 510000},
    {"date": "2026-08-12", "status": "for_sale", "price": 499000},
    {"date": "2026-08-30", "status": "pending", "price": 499000},
    {"date": "2026-09-25", "status": "sold", "price": 492000},
]
for e in price_events(SNAPS):
    print(e["date"], e["type"], e["price"], e["change_pct"])

Sáu bản ghi sinh ra năm sự kiện: đăng bán ở 525.000 USD, hai lần giảm giá còn 510.000 rồi 499.000, chuyển sang chờ giao dịch và bán ở 492.000. Bản ghi ngày 08/07 không sinh sự kiện vì không có gì đổi. Lần giảm đầu là âm 2,86%, giá bán thấp hơn giá chờ giao dịch 1,4%.

Câu hỏi phân tích từ bảng sự kiện

Khi sự kiện đã nằm trong bảng, các câu hỏi phổ biến chỉ còn là truy vấn. Danh sách dưới là vài câu ProxyVN thấy người làm dữ liệu bất động sản hay hỏi.

  • Tỷ lệ tin có ít nhất một lần giảm giá trong 30 ngày đầu.
  • Mức giảm trung vị của lần giảm đầu tiên theo vùng.
  • Số ngày trung vị từ lúc đăng tới lúc chờ giao dịch.
  • Chênh lệch trung vị giữa giá rao cuối và giá bán.

Kết hợp với ZHVI, anh em so được diễn biến giá rao của một nhóm tin với xu hướng giá trị nhà của cả vùng. Sự kiện giá cho biết người bán đang làm gì, chỉ số vùng cho biết thị trường đang đi đâu. Tóm lại, theo dõi thay đổi giá là bài toán biến trạng thái thành sự kiện, và hàm price_events là phần lõi của nó.

Kiểm tra dữ liệu khi crawl Zillow bằng Python

Dữ liệu bất động sản có nhiều kiểu lỗi đặc thù: giá nhập thiếu một số không, giá thuê lẫn vào giá bán, căn bị rao trùng ở hai mã tin. Một bước kiểm tra tự động giúp loại phần lớn lỗi trước khi chúng vào báo cáo. Phần này dựng bước kiểm tra đó.

Sự kiện giá của một tin rao

Sự kiện giá của một tin rao

Quy tắc kiểm tra sự kiện giá

Hàm validate_events gắn cờ các sự kiện bất thường thay vì xoá chúng. Người phân tích quyết định giữ hay loại sau khi xem. Ngưỡng trong code là điểm khởi đầu, anh em chỉnh theo phân khúc thị trường đang theo dõi.

def validate_events(events, min_price=10000, max_jump_pct=40):
    flags = []
    for e in events:
        if e["price"] is not None and e["price"] < min_price:
            flags.append((e["date"], "giá thấp bất thường, có thể là giá thuê"))
        if e["change_pct"] is not None and abs(e["change_pct"]) > max_jump_pct:
            flags.append((e["date"], f"đổi giá {e['change_pct']}%, kiểm tra lỗi nhập"))
    return flags
 
BAD = SNAPS + [{"date": "2026-10-05", "status": "for_sale", "price": 4920}]
print(validate_events(price_events(BAD)))

Bản ghi lỗi cố ý thêm vào có giá 4.920 USD, giống lỗi thiếu hai số không. Kết quả lab gắn hai cờ cho cùng ngày: giá thấp bất thường và mức đổi giá âm 99%. Một lỗi nhập liệu có thể làm sai lệch trung vị giảm giá của cả vùng nếu không bị phát hiện.

Kiểm tra chuỗi ZHVI

Với chuỗi chỉ số theo vùng, kiểm tra đơn giản nhất là mức thay đổi theo tháng. Chỉ số làm mượt hiếm khi đổi quá vài phần trăm trong một tháng. Truy vấn dưới dùng hàm ngày giờ của SQLite để ghép mỗi tháng với tháng liền trước. Một bước nhảy lớn thường do tải nhầm tệp, ví dụ lẫn bản thô với bản làm mượt, hoặc lẫn cấp vùng.

def monthly_jumps(con, limit_pct=3.0):
    return con.execute("""SELECT a.region, a.month, a.zhvi, b.zhvi FROM zhvi a
        JOIN zhvi b ON a.region_id = b.region_id
        AND b.month = strftime('%Y-%m', date(a.month || '-01', '-1 month'))
        WHERE ABS(a.zhvi - b.zhvi) / b.zhvi * 100 > ?""", (limit_pct,)).fetchall()
 
print("Bước nhảy lớn:", monthly_jumps(con))

Bộ mẫu không có bước nhảy nào vượt 3% giữa hai tháng liền kề, nên kết quả là danh sách rỗng. Khi chạy với tệp thật, danh sách khác rỗng là tín hiệu để mở lại tệp gốc kiểm tra.

Ghi nguồn và thời điểm

Mỗi bảng nên có cột hoặc bảng phụ ghi nguồn tệp, đường dẫn và ngày tải. Zillow Research có hướng dẫn trích dẫn riêng cho ZHVI, anh em làm theo khi công bố số liệu. Với dữ liệu cấp phép, điều khoản của nhà cung cấp quy định cách ghi nguồn và giới hạn hiển thị.

Tóm lại, kiểm tra dữ liệu bất động sản tập trung vào giá bất thường và bước nhảy bất thường, cộng với việc ghi nguồn đầy đủ để truy ngược khi cần.

Xử lý lỗi khi crawl Zillow bằng Python

Vì bài không đọc trang Zillow, phần lớn lỗi nằm ở bước tải tệp và bước nhận dữ liệu từ kênh cấp phép. Mỗi loại lỗi có dấu hiệu riêng. Danh sách dưới gom những lỗi hay gặp và cách xử lý.

Lỗi khi tải tệp nghiên cứu

Tệp ZHVI tải qua HTTPS từ máy chủ tệp tĩnh. Lỗi thường gặp nhất là đường dẫn đổi sau khi trang dữ liệu được cập nhật. Các lỗi còn lại liên quan tới kích thước tệp và mã hoá ký tự.

  • 404 khi tải tệp: đường dẫn đã đổi; mở lại trang Zillow Research lấy đường dẫn mới.
  • Timeout với tệp cấp ZIP: tăng thời gian chờ đọc, tải theo luồng.
  • UnicodeDecodeError: kiểm tra lại mã hoá, tên vùng có ký tự đặc biệt.
  • Số cột tháng giảm: có thể tải nhầm bản khác, so tên tệp với cấu hình.

Với lỗi 403 hay trang chặn khi truy cập trang web của Zillow, ProxyVN khuyên dừng lại. Đó là tín hiệu Zillow không muốn truy cập tự động vào khu vực đó, không phải lỗi kỹ thuật cần vượt qua.

Lỗi dữ liệu từ kênh cấp phép

Nhà cung cấp dữ liệu MLS thường có tài liệu riêng về trường dữ liệu và mã trạng thái. Lỗi phổ biến là ánh xạ sai trạng thái, ví dụ coi trạng thái tạm hoãn là đã rút tin. Trước khi chạy hàm price_events, anh em lập bảng ánh xạ trạng thái của nhà cung cấp sang năm trạng thái trong bài.

Một lỗi khác là bản ghi đến không theo thứ tự thời gian. Hàm price_events đã sắp xếp theo ngày trước khi xử lý, nhưng nếu hai bản ghi cùng ngày, thứ tự giữa chúng không xác định. Thêm trường giờ cập nhật nếu nguồn có cung cấp.

Lỗi trùng tin

Một căn rao lại sau khi rút tin thường mang mã tin mới. Nhờ property_key, anh em nối được các lần rao của cùng căn. Khi phân tích thời gian bán, cần quyết định tính từ lần rao đầu hay lần rao cuối, và ghi rõ lựa chọn trong báo cáo.

Tóm lại, lỗi trong dự án dữ liệu bất động sản đến nhiều từ ánh xạ và thứ tự hơn là từ kết nối mạng. Bảng ánh xạ trạng thái và khoá căn nhà giải quyết phần lớn các lỗi này.

Khi nào cần proxy cho crawl Zillow bằng Python

Với hướng dữ liệu trong bài, proxy gần như không cần. Tệp Zillow Research tải được từ máy cá nhân, dữ liệu cấp phép đi qua kênh có xác thực riêng. Proxy chỉ có vai trò trong vài tình huống hạ tầng.

Tình huống hợp lý

Tình huống đầu tiên là mạng công ty bắt buộc đi qua proxy khi tải tệp từ Internet. Khi đó, Session của Requests khai báo proxy rõ ràng là đủ. Tình huống thứ hai là nhà cung cấp dữ liệu cấp phép yêu cầu đăng ký IP cố định được phép gọi API. Một IP datacenter tĩnh giúp đáp ứng yêu cầu này mà không phụ thuộc IP văn phòng thay đổi.

Tình huống thứ ba là đội nghiên cứu ở Việt Nam cần kiểm tra thủ công cách một trang công khai hiển thị với người xem ở Mỹ, ví dụ trang dữ liệu nghiên cứu hoặc trang giới thiệu dịch vụ. Đây là thao tác của người, không phải kịch bản thu thập. Bài proxy dữ liệu bất động sản trên blog ProxyVN bàn thêm về các nhu cầu mạng của ngành này.

Tình huống không dùng proxy

Không dùng proxy xoay để vượt hệ thống chống bot của Zillow hay để đọc trang tin rao hàng loạt. Thông báo truy cập bị từ chối mà ProxyVN gặp khi mở trang điều khoản là ví dụ cho thấy Zillow chủ động ngăn truy cập tự động. Vượt qua lớp này là đi ngược ý chí rõ ràng của chủ website.

Với Zillow, câu hỏi đúng không phải dùng bao nhiêu IP mà là dữ liệu này đã có ở dạng tải công khai hoặc cấp phép chưa. Phần lớn trường hợp, câu trả lời là có.

Gói phù hợp

Nếu cần IP tĩnh để đăng ký với nhà cung cấp dữ liệu, gói datacenter US là lựa chọn gần với hạ tầng của nhà cung cấp ở Mỹ. Anh em có thể mua proxy giá rẻ dạng datacenter US hoặc datacenter Việt Nam tại trang chủ ProxyVN, sau đó kiểm tra IP đi ra trước khi gửi cho nhà cung cấp đăng ký. Để hiểu thêm về thu thập dữ liệu theo khu vực, xem bài proxy nghiên cứu thị trường.

Tóm lại, proxy trong dự án Zillow phục vụ hạ tầng và đăng ký IP, không phục vụ việc lấy dữ liệu từ trang hiển thị.

Checklist trước khi crawl Zillow bằng Python chạy thật

Danh sách dưới gom các bước trong bài thành việc cần kiểm tra trước khi đưa kịch bản vào chạy định kỳ. Anh em chia theo ba nhóm: quyền, dữ liệu và vận hành.

Checklist quyền, dữ liệu, vận hành

Checklist quyền, dữ liệu, vận hành

Nhóm quyền

Nhóm này quyết định dự án có được phép tồn tại hay không. Mọi nguồn mới phải qua đủ các mục.

  • Đã đọc điều khoản Zillow bằng trình duyệt thông thường và ghi ngày đọc.
  • Câu hỏi cấp thị trường dùng dữ liệu Zillow Research tải công khai.
  • Dữ liệu cấp tin rao đến từ MLS, nhà cung cấp cấp phép hoặc dữ liệu của chính văn phòng.
  • Không lưu thông tin chủ nhà hay liên hệ cá nhân.

Nhóm dữ liệu

Nhóm này đảm bảo bảng dữ liệu đúng và truy ngược được. Rà lại mỗi khi thêm nguồn hoặc đổi định dạng.

  • ZHVI lưu dạng dài với khoá vùng và tháng.
  • Ba bảng properties, listings, price_events tách riêng.
  • property_key dựa trên địa chỉ chuẩn hoá và ZIP năm số.
  • Có kiểm tra giá bất thường và bước nhảy bất thường.
  • Có bảng ánh xạ trạng thái của nhà cung cấp.

Nhóm vận hành

Nhóm này giúp kịch bản chạy đều. Dữ liệu nghiên cứu cập nhật theo tháng, dữ liệu cấp phép theo lịch của nhà cung cấp.

  • Tải ZHVI một lần mỗi tháng sau ngày công bố.
  • Đường dẫn tệp lưu trong cấu hình, không viết cứng.
  • Ghi nguồn, đường dẫn và ngày tải cho mọi lần nhập.

Kết luận cho checklist: kịch bản bất động sản đáng tin là kịch bản trả lời được câu hỏi "số liệu này lấy từ đâu, khi nào" cho mọi con số trong báo cáo.

Crawl Zillow bằng Python bền vững là tải dữ liệu Zillow Research cho câu hỏi thị trường, nhận dữ liệu tin rao qua kênh cấp phép và lưu thay đổi giá thành sự kiện riêng. Đọc điều khoản trước, dữ liệu sau. Cần hỗ trợ IP tĩnh cho nguồn cấp phép, anh em nhắn Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam trước khi crawl Zillow bằng Python.

TIN TỨC LIÊN QUAN