Cào Website Động

Các trang web động tải nội dung bằng JavaScript sau lần tải trang ban đầu. Hướng dẫn này chỉ ra cách thu thập dữ liệu từ các trang web này bằng browser endpoint của FourA.

Vấn đề

Khi bạn gửi một HTTP request tiêu chuẩn đến một trang web sử dụng nhiều JavaScript, bạn chỉ nhận được khung HTML chứ không có nội dung thực tế. Dữ liệu bạn cần (danh sách sản phẩm, giá cả, kết quả tìm kiếm) được JavaScript tải sau khi trang hiển thị trong trình duyệt.

Điều này ngày càng phổ biến với các framework hiện đại như React, Vue, Angular và Next.js.

Giải pháp: Browser Request

Browser endpoint của FourA (POST /api/browser/) mở URL của bạn trong một phiên bản trình duyệt Chrome nhằm:

  1. Tải trang
  2. Thực thi toàn bộ JavaScript
  3. Chờ nội dung hiển thị (render)
  4. Trả về HTML đã được render đầy đủ

Bước 1: Xác định những gì bạn cần

Trước khi tạo request, hãy truy cập trang đích trong trình duyệt của bạn và sử dụng DevTools (F12) để tìm một đoạn văn bản hoặc phần tử xác nhận nội dung đã được tải. Ví dụ:

  • Tên sản phẩm xuất hiện sau khi JS render
  • Một CSS class như product-grid trong HTML đã render
  • Một chuỗi văn bản như "results" chỉ xuất hiện khi dữ liệu được tải

Bước 2: Gửi một Browser Request

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
  }'

Tùy chọn checkText yêu cầu FourA kiểm tra xem "product-grid" có xuất hiện trên trang sau khi tải xong hay không. Nếu không có, request sẽ trả về thất bại với checkText:product-grid not found, và request thất bại sẽ không bị tính phí. checkText không làm cho FourA phải đợi văn bản lâu hơn.

Bước 3: Phân tích cú pháp HTML

Response chứa HTML đã được render đầy đủ trong trường body. Phân tích cú pháp bằng thư viện bạn muốn:

Python (BeautifulSoup)

import requests
from bs4 import BeautifulSoup

resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}, json={
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
})

html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")

for product in soup.select(".product-card"):
    name = product.select_one(".product-name").text.strip()
    price = product.select_one(".product-price").text.strip()
    print(f"{name}: {price}")

Node.js (cheerio)

import * as cheerio from 'cheerio';

const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/products',
    timeout_ms: 15000,
    checkText: 'product-grid'
  })
});

const { body: html } = await resp.json();
const $ = cheerio.load(html);

$('.product-card').each((i, el) => {
  console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});

Xử lý sự cố

Vẫn nhận được nội dung trống?

  • Xác minh xem trang có thực sự sử dụng kết xuất JavaScript không (kiểm tra bằng "View Source" so với DevTools)
  • Tăng timeout_ms: một số trang tải chậm
  • Kiểm tra xem trang có yêu cầu xác thực hoặc cookie không (sử dụng tham số cookies)

Gặp trang xác minh?

  • Đối với các request đơn lẻ/HTTP, hãy chuyển sang endpoint proxy (POST /api/proxy/) để tự động xoay vòng IP.
  • Để định tuyến request trình duyệt qua proxy, hãy truyền tham số proxy của endpoint trình duyệt. Endpoint proxy chỉ bao bọc các request đơn lẻ/HTTP, không hỗ trợ request trình duyệt.

Tham số proxy nhận proxy ID dạng opaque mà response trước đó trả về, tuyệt đối không dùng địa chỉ proxy riêng của bạn. Hãy chạy một lệnh gọi POST /api/proxy/ (hoặc POST /api/auto/) trước, đọc trường proxy được trả về, sau đó ghim nó:

# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'

# Step 2: render through that same exit.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/products", "proxy": "A1B2C3", "timeout_ms": 20000}'

Gửi một địa chỉ thay vì một ID sẽ trả về 400 Invalid proxy format. Cấu trúc mẫu đầy đủ có trong Tái sử dụng Proxy qua nhiều Request.

Các bước tiếp theo

Cập nhật: 27 tháng 9, 2026