Scarnox · Blog

Theo dõi giá bằng web scraping: hướng dẫn thực tế

Theo dõi giá nghĩa là kiểm tra giá một sản phẩm trên một tập hợp các trang, theo lịch, và ghi lại những gì bạn thấy để so sánh theo thời gian. Nhà bán lẻ, sàn thương mại và nhà phân tích đều dùng nó. Scraping giá cũng là một trong những cách phổ biến nhất để scraper gặp captcha, nên đáng để thiết kế đúng ngay từ đầu. Hướng dẫn này bao quát những gì nên theo dõi, cách phân tích số từ các trang vốn không được thiết kế để phân tích, cách lưu trữ và cảnh báo khi có thay đổi, và cách vẫn nằm trong quy định của trang khi làm việc đó.

Bắt đầu từ nguồn bạn được phép dùng

Trước khi viết bất kỳ code nào, hãy kiểm tra xem trang có cung cấp cách chính thức để lấy dữ liệu không: một feed sản phẩm, một API, hoặc một chương trình đối tác. Những cách này đáng tin cậy hơn scraping và loại bỏ phần lớn rủi ro pháp lý lẫn kỹ thuật. Scraping là phương án dự phòng cho các trang công khai khi không có đường chính thức, và điều khoản cùng robots.txt vẫn áp dụng. Tổng quan pháp lý bao quát các câu hỏi chung.

Kiến trúc gồm năm phần

Một công cụ theo dõi đáng tin cậy có năm phần, và tách chúng ra giúp dễ gỡ lỗi hơn:

  1. Bộ lập lịch. Quyết định trang sản phẩm nào cần ghé thăm và khi nào. Trải các lần ghé thăm ra suốt trong ngày thay vì kiểm tra mọi thứ cùng một phút.
  2. Bộ tải. Tải trang, với nhịp độ lịch sự, retry và cache.
  3. Bộ phân tích. Trích xuất giá, bối cảnh tiền tệ và trạng thái tồn kho.
  4. Kho lưu trữ. Giữ mọi quan sát kèm dấu thời gian, để bạn có lịch sử.
  5. Bộ cảnh báo. So sánh giá mới với giá trước đó và thông báo khi vượt qua ngưỡng bạn đặt.

Phân tích giá từ trang lộn xộn

Giá xuất hiện dưới nhiều dạng: có dấu phân cách hàng nghìn, có dấu phẩy thập phân, có nhãn đứng trước con số, hoặc bị tách ra nhiều phần tử. Hãy giữ bộ phân tích nhỏ gọn và kiểm thử nó với các ví dụ thật. Đây là một phiên bản giả định định dạng phổ biến với dấu phẩy cho hàng nghìn và dấu chấm cho thập phân. Hãy chuẩn hóa các định dạng khác trước khi gọi nó.

import re
from decimal import Decimal, InvalidOperation

PRICE_PATTERN = re.compile(r"\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|\d+(?:\.\d{1,2})?")

def parse_price(text: str) -> Decimal | None:
    """Trả về số đầu tiên trong văn bản dưới dạng Decimal, hoặc None."""
    match = PRICE_PATTERN.search(text.replace(" ", " "))
    if not match:
        return None
    try:
        return Decimal(match.group(0).replace(",", ""))
    except InvalidOperation:
        return None

print(parse_price("Now 1,249.50 in stock"))  # Decimal('1249.50')
print(parse_price("Sold out"))               # None

Dùng Decimal, không dùng float, cho bất cứ thứ gì bạn sẽ so sánh hoặc cộng tổng. Sai số làm tròn dấu phẩy động có thể khiến hai giá bằng nhau trông khác nhau. Hãy giữ văn bản thô bên cạnh giá đã phân tích, để bạn sửa lỗi bộ phân tích sau này mà không phải tải lại mọi trang.

Lưu lịch sử và phát hiện thay đổi

Một giá đơn lẻ chỉ là một ảnh chụp. Giá trị của công cụ theo dõi nằm ở lịch sử. Lưu một dòng cho mỗi quan sát, gồm mã sản phẩm, nguồn, dấu thời gian, giá đã phân tích và văn bản thô. Khi đó, cảnh báo chỉ là một phép so sánh đơn giản với dòng trước. Chỉ cảnh báo khi có thay đổi đáng kể, như giảm vượt một tỷ lệ phần trăm đặt sẵn, hoặc sản phẩm hết hàng, để bạn không bị ngập trong nhiễu.

Xử lý biến thể và combo

Một trang sản phẩm thường hiển thị nhiều giá: mỗi kích cỡ hoặc màu một giá, giá combo, giá thành viên, hoặc giá chỉ xuất hiện sau khi chọn một tùy chọn. Hãy quyết định trước khi xây dựng xem công cụ nên ghi lại gì. Cách phổ biến là lưu mã biến thể kèm theo giá, để thay đổi ở một kích cỡ không trông giống như thay đổi của cả sản phẩm. Hãy cẩn thận với giá "từ" và giá gốc bị gạch ngang, vì một bộ phân tích lấy nhầm con số sẽ tạo ra cảnh báo sai. Lưu văn bản nhãn bên cạnh mỗi giá, để bạn kiểm tra được điều gì đã được đọc khi một cảnh báo có vẻ sai.

Lập lịch một cách lịch sự

Kiểm tra mỗi sản phẩm theo khoảng thời gian khớp với tần suất giá thực sự thay đổi. Một sản phẩm đổi giá hàng ngày không cần kiểm tra mỗi giờ. Thêm độ lệch ngẫu nhiên cho mỗi lần ghé thăm, giới hạn số request mỗi trang trong một giờ, và cache kết quả trong khoảng thời gian bạn đã chọn. Những thói quen này giữ tải của bạn thấp và dữ liệu của bạn nhất quán.

Khi trang chặn bạn

Các trang giá thường là mục tiêu của truy cập tự động, nên bạn có thể gặp chặn, giới hạn tốc độ hoặc captcha. Hãy lùi lại khi thấy 429 hoặc 503, và ngừng ghé thăm một trang liên tục từ chối bạn. Nếu captcha xuất hiện trên một trang bạn được phép tự động hóa, loại captcha đang hoạt động tại Scarnox là PopularCaptcha. Hướng dẫn Python cho PopularCaptcha chỉ cách luồng token. Đọc scrape mà không bị chặn trước khi thêm nhiều máy móc hơn, vì giữ nhịp độ thường giải quyết được nhiều hơn bất kỳ công cụ phụ trợ nào.

Một số trang render giá bằng JavaScript. Với những trang đó, làm theo cách trong scrape website JavaScript.

Scrape có trách nhiệm

Bước tiếp theo

Bắt đầu với tín dụng dùng thử miễn phí, không cần thẻ: tạo tài khoản và thử luồng PopularCaptcha trên một trang bạn được phép tự động hóa. Xem giá hiện tại tại trang giá.