← Quay lại blog

API ẩn thay vì phân tích HTML: cách giảm lưu lượng và chi phí proxy gấp 10 lần

Phân tích lý do tại sao việc phân tích các trang HTML tiêu tốn ngân sách cho proxy và chỉ ra cách chuyển sang các API ẩn - với việc giảm lưu lượng truy cập thực tế gấp 10 lần.

📅27 tháng 9, 2026

Nếu bạn đang parsing Wildberries, Ozon hoặc bất kỳ trang web nào khác thông qua việc tải xuống các trang HTML đầy đủ, bạn đang trả cho băng thông proxy gấp 5-10 lần so với những gì bạn có thể. Mỗi trang sản phẩm là 200-800 KB mã, script và kiểu dáng, trong đó bạn chỉ cần một vài trường: giá, tình trạng, đánh giá. Trong bài viết này, chúng ta sẽ tìm hiểu cách tìm API ẩn của trang web và nhận được những dữ liệu tương tự trực tiếp, ở định dạng JSON gọn nhẹ.

Tại sao parsing HTML tiêu tốn băng thông proxy

Khi parser tải một trang thông qua yêu cầu HTTP thông thường hoặc qua trình duyệt headless (Selenium, Puppeteer, Playwright), máy chủ sẽ trả về tài liệu HTML đầy đủ: mã, script inline, kiểu dáng, đôi khi là hình ảnh base64 và hàng trăm dòng JSON với dữ liệu cho các widget quảng cáo mà bạn không cần. Một thẻ sản phẩm trung bình trên Wildberries nặng 300-600 KB, trên Ozon lên tới 800 KB, nếu tính tất cả các tài nguyên liên quan (CSS, phông chữ, tracker).

Nếu bạn theo dõi 10.000 sản phẩm mỗi ngày qua 3 phiên proxy, điều này dễ dàng dẫn đến hàng chục gigabyte băng thông mỗi tháng. Proxy cư trú và di động thường được bán theo băng thông, vì vậy mỗi megabyte thừa đều là chi phí trực tiếp. Trong khi đó, dữ liệu thực tế mà bạn cần - giá, giảm giá, số lượng tồn kho, đánh giá - chỉ chiếm 1-5 KB trong phản hồi JSON. Sự khác biệt về khối lượng lên tới 100-200 lần cho mỗi sản phẩm, và nếu tính đến chi phí phát sinh cho việc render trình duyệt - tiết kiệm về thời gian và CPU còn lớn hơn nữa.

Một vấn đề bổ sung của parsing HTML là sự mong manh. Các trang web marketplace thường xuyên thay đổi bố cục, lớp CSS, cấu trúc DOM. Mỗi thay đổi như vậy đều làm hỏng parser được xây dựng trên XPath hoặc CSS selectors. API nội bộ thay đổi ít hơn nhiều, vì nó phụ thuộc vào việc hoạt động của ứng dụng di động và frontend của trang web đồng thời.

API ẩn là gì và nó đến từ đâu

Hầu hết các trang web hiện đại đều là SPA (Single Page Application) hoặc ứng dụng hybrid, nơi trình duyệt trước tiên tải "khung" của trang, sau đó thông qua JavaScript thực hiện các yêu cầu bổ sung đến API nội bộ để lấy dữ liệu thực: giá cả, số lượng tồn kho, đánh giá, khuyến nghị. Những yêu cầu này được gọi là API ẩn hoặc nội bộ - chúng không được tài liệu công khai, nhưng hoàn toàn mở trong băng thông của trình duyệt.

Về mặt kỹ thuật, đây thường là các endpoint REST hoặc GraphQL, trả về dữ liệu ở định dạng JSON. Ví dụ, trên Wildberries, thẻ sản phẩm được tải qua các yêu cầu như card.wb.ru và wbx-content-v2.wbstatic.net, trong khi giá cả và số lượng tồn kho được gửi qua yêu cầu riêng đến basket-01.wb.ru và các miền tương tự. Ozon có logic tương tự: frontend truy cập vào API composer nội bộ, tổng hợp dữ liệu từ các microservices.

Quan trọng là phải hiểu rằng việc sử dụng API như vậy về mặt hình thức không phải là hack - bạn chỉ đang lặp lại các yêu cầu mà trình duyệt của người dùng thông thường thực hiện. Nhưng các trang web bảo vệ các endpoint này thông qua các hệ thống chống bot, vì vậy cần phải mô phỏng hành vi của khách hàng thực một cách cẩn thận, bao gồm cả việc sử dụng proxy chất lượng.

Cách tìm API ẩn qua DevTools

Bạn có thể tìm API nội bộ mà không cần một dòng mã nào, sử dụng các công cụ tích hợp sẵn của trình duyệt Chrome hoặc Firefox. Dưới đây là thuật toán từng bước:

  1. Mở trang sản phẩm cần thiết trong Chrome, nhấn F12 và chuyển đến tab Network.
  2. Trong bộ lọc yêu cầu, chọn loại Fetch/XHR - như vậy bạn sẽ loại bỏ việc tải hình ảnh, phông chữ và tĩnh.
  3. Tải lại trang (F5) và xem danh sách các yêu cầu xuất hiện sau khi tải khung của trang.
  4. Tìm yêu cầu mà trong phản hồi của nó (tab Response) có thể thấy giá sản phẩm, tên hoặc các trường cần thiết khác ở định dạng JSON.
  5. Nhấp vào yêu cầu này và sao chép nó dưới dạng cURL (nhấp chuột phải → Copy → Copy as cURL) - điều này sẽ cung cấp cho bạn toàn bộ tập hợp tiêu đề, cookie và tham số.
  6. Kiểm tra xem các tham số nào trong URL là bắt buộc (mã sản phẩm, khu vực, phiên bản API), và tham số nào có thể loại bỏ mà không mất dữ liệu.

Sau đó, chỉ cần lặp lại yêu cầu này thông qua thư viện HTTP thông thường, thay thế mã sản phẩm hoặc ID sản phẩm cần thiết thay vì phải render toàn bộ trang. Điều này hoạt động cho hầu hết các marketplace - Wildberries, Ozon, Avito, cũng như cho nhiều nền tảng nước ngoài như Amazon và eBay.

So sánh băng thông: HTML vs JSON API

Sự khác biệt về khối lượng dữ liệu lớn đến mức cần phải thể hiện nó bằng con số. Dưới đây là các đo lường trung bình cho một thẻ sản phẩm trên các marketplace phổ biến.

Cách parsing Kích thước phản hồi trung bình Thời gian tải Cần render JS không
HTML đầy đủ qua Selenium 400-800 KB 1.5-4 giây Có
Yêu cầu HTTP đơn giản (requests) 150-300 KB 0.3-0.8 giây Không
API JSON ẩn 3-15 KB 0.1-0.3 giây Không

Khi theo dõi 50.000 sản phẩm mỗi ngày, việc chuyển từ trình duyệt headless sang các yêu cầu trực tiếp đến API giảm băng thông từ khoảng 30-40 GB xuống còn 300-700 MB mỗi tháng. Đây không chỉ là tiết kiệm chi phí băng thông proxy, mà còn giảm tải cho hạ tầng máy chủ của parser - ít CPU hơn cho việc render, ít bộ nhớ hơn, nhanh hơn trong việc thu thập dữ liệu.

Ví dụ thực tiễn trên Python

Hãy xem xét một ví dụ đơn giản: lấy giá và số lượng tồn kho của sản phẩm thông qua yêu cầu trực tiếp đến API nội bộ thay vì tải toàn bộ trang. Đây là mẫu học - các endpoint và tham số chính xác cần được xác định qua DevTools cho trang web cụ thể, vì cấu trúc của các yêu cầu có thể khác nhau tùy thuộc vào khu vực và phiên bản API.

import requests

def get_product_data(product_id: str, proxies: dict = None) -> dict:
    """
    Nhận dữ liệu sản phẩm thông qua API nội bộ thay vì HTML đầy đủ.
    proxies - từ điển với proxy theo định dạng requests: {"http": "...", "https": "..."}
    """
    url = f"https://card.example-marketplace.ru/v2/detail"
    params = {
        "nm": product_id,
        "dest": "-1257786",  # khu vực, xác định qua DevTools
        "spp": "0"
    }
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                       "AppleWebKit/537.36 (KHTML, like Gecko) "
                       "Chrome/120.0 Safari/537.36",
        "Accept": "application/json",
        "Referer": f"https://www.example-marketplace.ru/catalog/{product_id}/detail.aspx"
    }

    response = requests.get(
        url,
        params=params,
        headers=headers,
        proxies=proxies,
        timeout=10
    )
    response.raise_for_status()
    data = response.json()

    product = data["products"][0]
    return {
        "id": product["id"],
        "name": product["name"],
        "price": product["salePriceU"] / 100,
        "stock": product.get("totalQuantity", 0),
        "rating": product.get("reviewRating", None)
    }


if __name__ == "__main__":
    proxy = {
        "http": "http://user:pass@proxy-host:port",
        "https": "http://user:pass@proxy-host:port"
    }
    result = get_product_data("123456789", proxies=proxy)
    print(result)

Lưu ý ba điểm trong ví dụ này. Thứ nhất, chúng ta chỉ định tiêu đề Referer, vì nhiều API kiểm tra rằng yêu cầu đến từ "trình duyệt", chứ không phải trực tiếp qua URL. Thứ hai, chúng ta sử dụng User-Agent thực tế, chứ không phải mặc định từ thư viện requests, dễ dàng bị phát hiện. Thứ ba, toàn bộ yêu cầu được thực hiện trong một cuộc gọi HTTP mà không cần render - đây là điều mang lại lợi thế lớn về băng thông và tốc độ.

Đối với các endpoint GraphQL, logic tương tự, nhưng thay vì các tham số GET, bạn gửi yêu cầu POST với nội dung yêu cầu ở định dạng JSON, trong đó bạn liệt kê rõ ràng các trường cần thiết - điều này còn giảm thêm khối lượng phản hồi, vì máy chủ chỉ trả về dữ liệu được yêu cầu.

Làm việc với proxy khi gửi yêu cầu đến API

Ngay cả khi chuyển sang định dạng JSON gọn nhẹ, bạn vẫn cần proxy - các marketplace giới hạn số lượng yêu cầu từ một IP và sẽ cấm khi có hoạt động bất thường. Việc chọn loại proxy phù hợp ở đây ảnh hưởng trực tiếp đến sự ổn định của parser.

Để vượt qua API của các marketplace như Wildberries hoặc Ozon, proxy từ trung tâm dữ liệu rất phù hợp - chúng cung cấp tốc độ cao và chi phí băng thông thấp, điều này rất quan trọng khi gửi yêu cầu thường xuyên đến các endpoint JSON nhẹ. Nhưng nếu API cụ thể được bảo vệ bởi hệ thống chống bot nghiêm ngặt hơn và cấm toàn bộ các subnet từ trung tâm dữ liệu, thì hợp lý hơn là chuyển sang proxy cư trú - chúng sử dụng địa chỉ IP thực của người dùng tại nhà và ít bị chặn hơn theo subnet.

Đối với các API liên quan đến ứng dụng di động (một số phiên bản endpoint Avito hoặc marketplace chỉ cung cấp dữ liệu qua băng thông di động), có thể cần kết nối qua proxy di động - chúng mô phỏng băng thông của các nhà mạng thực và vượt qua các kiểm tra chặn các IP thông thường.

Khi thiết lập proxy trong parser, cũng quan trọng là phân bổ các yêu cầu theo thời gian và sử dụng xoay vòng IP - ngay cả một yêu cầu JSON gọn nhẹ, được lặp lại 1000 lần mỗi phút từ một địa chỉ, cũng sẽ gây nghi ngờ cho hệ thống bảo vệ. Hãy thiết lập một nhóm từ nhiều phiên proxy và phân phối tải giữa chúng, thêm các độ trễ ngẫu nhiên từ 1-3 giây giữa các yêu cầu.

Cạm bẫy: token, chữ ký, chống bot

Các API ẩn không phải lúc nào cũng mở cửa hoàn toàn. Một số trang web bảo vệ các endpoint của mình bằng các cơ chế bổ sung, cần phải xem xét khi xây dựng parser.

  • Token phiên tạm thời - một số API yêu cầu yêu cầu trước để lấy token, sau đó được truyền trong tiêu đề của các yêu cầu tiếp theo và có thời gian sống hạn chế (thường là 5-30 phút).
  • Chữ ký yêu cầu (signature) - các tham số yêu cầu được băm trên client với khóa bí mật từ mã JS của trang. Chữ ký này cần phải được tái tạo thủ công, phân tích thuật toán, hoặc thực hiện qua trình duyệt headless chỉ trong giai đoạn lấy token, và sau đó gửi các yêu cầu nhẹ trực tiếp.
  • Giới hạn tần suất theo IP và User-Agent - khi vượt quá tần suất yêu cầu, trang web sẽ tạm thời chặn quyền truy cập. Điều này được giải quyết bằng cách xoay vòng proxy và các độ trễ hợp lý.
  • Kiểm tra fingerprinting tiêu đề - một số hệ thống kiểm tra toàn bộ tập hợp tiêu đề (thứ tự, sự hiện diện của Accept-Language, Sec-Fetch-*) và chặn các yêu cầu với tập hợp "không đầy đủ", đặc trưng cho các script, chứ không phải trình duyệt.
  • Phụ thuộc địa lý của dữ liệu - giá cả và số lượng tồn kho trên các marketplace có thể khác nhau theo khu vực, vì vậy quan trọng là phải truyền tham số khu vực/nhà kho chính xác trong yêu cầu, nếu không dữ liệu sẽ không liên quan.

Nếu API bị khóa bằng chữ ký yêu cầu khó tái tạo, một lựa chọn thỏa hiệp là sử dụng trình duyệt headless (Playwright, Puppeteer) chỉ để chặn các yêu cầu mạng và trích xuất phản hồi JSON đã hoàn thành, mà không cần parsing DOM. Điều này chậm hơn so với yêu cầu HTTP trực tiếp, nhưng vẫn nhanh hơn và nhẹ hơn so với việc parsing toàn bộ bố cục của trang.

Danh sách kiểm tra trước khi khởi động parser trên API ẩn

  • Đã tìm thấy endpoint qua DevTools, sao chép dưới dạng cURL và thử nghiệm trong Postman hoặc qua requests.
  • Xác định các tham số yêu cầu bắt buộc (ID sản phẩm, khu vực, phiên bản API) và loại bỏ các tham số thừa.
  • Các tiêu đề User-Agent, Referer và Accept-Language được thiết lập thực tế.
  • Kiểm tra xem có cần token phiên hoặc chữ ký yêu cầu không, và suy nghĩ về cách lấy chúng.
  • Đã thiết lập xoay vòng proxy và các độ trễ ngẫu nhiên giữa các yêu cầu.
  • Chọn loại proxy phù hợp với bảo vệ cụ thể của trang web - trung tâm dữ liệu, cư trú hoặc di động.
  • Thêm xử lý lỗi 429 và 403 với việc tự động chuyển sang proxy khác.
  • Đã thiết lập ghi log khối lượng băng thông để kiểm soát tiết kiệm thực tế.

Kết luận

Việc chuyển từ parsing HTML đầy đủ sang làm việc với API ẩn không chỉ là tối ưu hóa kỹ thuật, mà còn là giảm chi phí cho băng thông proxy và hạ tầng. Thay vì tải hàng trăm kilobyte mã thừa, bạn nhận được JSON gọn nhẹ với đúng các trường cần thiết cho việc theo dõi giá cả, số lượng tồn kho hoặc đánh giá. Một lợi ích bổ sung - độ bền của parser trước những thay đổi trong bố cục của trang web, vì các API nội bộ thay đổi ít hơn frontend.

Tuy nhiên, chính phương pháp tìm kiếm API không loại bỏ sự cần thiết của proxy chất lượng - các hệ thống chống bot của các marketplace đều theo dõi cẩn thận cả các yêu cầu HTML và các yêu cầu đến các endpoint JSON. Nếu bạn theo dõi Wildberries hoặc Ozon với khối lượng lớn, hãy bắt đầu với các proxy từ trung tâm dữ liệu nhanh chóng để giảm chi phí, và khi có dấu hiệu đầu tiên của việc bị chặn, hãy chuyển sang các nhóm IP cư trú hoặc di động để có hoạt động ổn định hơn cho parser.