Tại sao proxy request đã dùng hết số lần thử

Vấn đề

Một lệnh gọi POST /api/proxy/ trả về lỗi và không có dữ liệu. Thông báo rất ngắn và luôn có cùng cấu trúc:

{
  "error": "Download maxTry limit reached",
  "total": 34.812,
  "request": { "...": "..." }
}

Câu đó đọc hoàn toàn giống nhau cho dù mọi exit bị chặn, mọi exit bị chết, hoặc FourA đã tìm nạp trang thực trên hầu như mọi lần thử và chính các quy tắc validate của bạn đã loại bỏ nó. Ba trường hợp đó cần các cách xử lý hoàn toàn trái ngược nhau.

Câu trả lời: attemptReport

Mỗi lệnh gọi Proxy đã chạy qua các lần thử và thất bại đều mang theo một đối tượng attemptReport bên cạnh lỗi, bao gồm cả lệnh gọi kết thúc với "error": "Timeout". Tên máy chủ không thể phân giải sẽ thất bại trước bất kỳ lần thử nào, kèm theo status: 0 và không có báo cáo. Nó thống kê những gì các lần thử thực sự đã gặp phải:

{
  "error": "Download maxTry limit reached",
  "attemptReport": {
    "total": 25,
    "noResponse": 0,
    "defense": 0,
    "contentRejected": 25,
    "statusRejected": 0,
    "other": 0,
    "vendors": [],
    "profilesTried": ["default"],
    "summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
  },
  "total": 34.812
}

Chuỗi error được giữ nguyên có chủ đích, giúp client khớp chuỗi này tiếp tục hoạt động bình thường. Đọc attemptReport.summary để nhận câu trả lời tóm tắt trên một dòng, hoặc xem các trường số đếm khi bạn muốn phân nhánh xử lý theo chúng.

Các trường

Trường Kiểu Nội dung đếm
total integer Số lượt thử đã thực hiện
noResponse integer Điểm thoát mạng không phản hồi, hoặc trang web không phản hồi kịp thời
defense integer Trang web đã phản hồi và phát hiện đơn vị cung cấp kiểm tra bot trong phản hồi đó
contentRejected integer HTTP 200, không có kiểm tra bot, chỉ bị từ chối bởi validate.data của bạn
statusRejected integer Trang web đã phản hồi, không có kiểm tra bot, bị từ chối bởi validate.status của bạn
other integer Đã phản hồi, và không thuộc các trường hợp trên
vendors string[] Mọi đơn vị cung cấp kiểm tra bot được phát hiện ở bất kỳ đâu trong tác vụ
profilesTried string[] Các hồ sơ trình duyệt mà tác vụ đã gửi, theo thứ tự sử dụng lần đầu. default nghĩa là request đã được gửi đi chính xác như bạn đã viết.
summary string Một câu được tạo từ các số đếm. An toàn để ghi log hoặc hiển thị cho người dùng.

Cách đọc thông tin

contentRejected có giá trị cao

Các trang đã được trả về. Quy tắc validate.data của bạn không khớp với chúng.

Đây là lỗi bạn có thể tự khắc phục, và cũng là lỗi mà mọi chỉ số khác đều che khuất: các request nhìn như thất bại ở mọi số liệu, nhưng FourA thực tế vẫn trả về nội dung thật trong suốt thời gian đó. Hãy fetch trang một lần qua POST /api/single/ và hoàn toàn không dùng validate, kiểm tra nội dung thực tế trả về, rồi viết lại quy tắc dựa trên nội dung đó.

Nguyên nhân phổ biến là áp dụng một quy tắc duy nhất cho một nhóm trang không giống nhau hoàn toàn. Một bộ chọn selector tồn tại trên các trang bài viết nhưng không có trên các trang video sẽ luôn thất bại mỗi khi gặp trang video, liên tục và tốn toàn bộ chi phí.

statusRejected có giá trị cao

Trang web đã phản hồi và quy tắc validate.status của bạn đã từ chối. Nếu các mã trạng thái đó là 401, 403, 429 hoặc 503, trang web đang từ chối client thay vì báo trang không tồn tại. Hãy thử:

  • Một hồ sơ trình duyệt khác (browser, os, version trên đối tượng request bên trong)
  • exitCountries nếu nội dung bị khóa theo khu vực
  • POST /api/browser/ nếu phản hồi từ chối cần JavaScript để xử lý

defense có giá trị cao

Kiểm tra bot đã được phát hiện trong các câu trả lời, và vendors chỉ rõ đó là loại nào. Xem Kiểm tra trang web để biết FourA hiện tự động vượt qua những hệ thống nào và chỉ báo cáo những hệ thống nào. Nếu đơn vị cung cấp không thuộc diện được xử lý trên endpoint này, hãy chuyển lệnh gọi sang POST /api/browser/ hoặc POST /api/auto/.

noResponse có giá trị cao

Các điểm thoát mạng hoàn toàn không phản hồi, vì vậy không thu thập được thông tin nào về mục tiêu. Hãy tăng maxTries, tăng timeout_ms, và kiểm tra xem URL có phân giải được từ internet công cộng hay không.

other có giá trị cao

Trang web đã phản hồi với một mã trạng thái, không phát hiện kiểm tra bot, và lượt thử thất bại vì lý do khác, chẳng hạn như quy tắc validate.headers. Một mục tiêu phản hồi chậm hơn timeout_ms của bạn sẽ được tính vào noResponse.

Luân chuyển hồ sơ trình duyệt

Khi một trang web từ chối trình duyệt mà FourA đã gửi, Proxy sẽ dừng yêu cầu bằng trình duyệt đó và thử một nhóm khác từ danh mục hồ sơ công khai. Việc này không tốn thêm lượt thử: cơ chế luân phiên thay đổi nội dung gửi trong lần thử lại, chứ không làm phát sinh thêm lần thử.

Proxy cũng ghi nhớ theo từng trang web về nhóm trình duyệt đã hoạt động thành công gần nhất tại đó sau khi trang web từ chối cấu hình mặc định. Một request sau đó tới trang web đó có thể bắt đầu ngay với nhóm trình duyệt này từ lần thử đầu tiên, và FourA sẽ chuyển sang nhóm tiếp theo khi trang web bắt đầu từ chối cả nhóm đó. Trình duyệt trên điện thoại chỉ được ghi nhớ cho các trang web phản hồi bằng JSON.

profilesTried là cách bạn theo dõi quá trình này diễn ra. Một mục nhập nghĩa là mọi lần thử đều gửi cùng một trình duyệt: default là request như đã khai báo, và catalogue id là nhóm trình duyệt mà FourA đã ghi nhớ trước đó cho trang web đó. Nhiều mục nhập nghĩa là quá trình luân phiên đã chạy và trang web đã từ chối từng trình duyệt trong số đó, đây là tình huống khác biệt so với việc chưa từng luân phiên.

Trên một response Proxy thành công, trường profile chỉ xuất hiện khi cơ chế luân phiên đã chọn một trình duyệt mà bạn không yêu cầu ban đầu:

{
  "status": 200,
  "data": "<!doctype html>...",
  "proxy": "A1B2C3",
  "profile": "...",
  "total": 4.108
}

Giá trị là ID danh mục từ GET /api/profiles. Vắng mặt có nghĩa là request đã được gửi đi chính xác như khi viết. Hiện diện có nghĩa là browser hoạt động không phải là browser bạn đã nhập, vì vậy hãy truyền lại ID đó dưới dạng profile trong các lệnh gọi tiếp theo thay vì phát lại browser đã thất bại. Trang tổng quan Playground thực hiện việc này cho bạn với Carry.

profile, browser, os, hoặc version được chỉ định rõ ràng trong request của bạn không bao giờ bị ghi đè. Tương tự đối với request mang header User-Agent hoặc Cookie của riêng bạn, vì clearance được liên kết với signature đã tạo ra nó.

Đọc trong mã nguồn

import requests

API = "https://eu.api.foura.ai"
H = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

r = requests.post(f"{API}/api/proxy/", headers=H, json={
    "maxTries": 5,
    "request": {
        "method": "GET",
        "url": "https://example.com/product/42",
        "validate": {"data": {"accept": ["Add to cart"]}},
    },
}).json()

if "error" in r:
    rep = r.get("attemptReport", {})
    print(rep.get("summary", r["error"]))

    if rep.get("contentRejected", 0) > rep.get("total", 0) / 2:
        # The pages arrived. The validate rule is what threw them away.
        raise SystemExit("validate.data did not match the real page")
    if rep.get("defense", 0):
        print("bot check met:", ", ".join(rep.get("vendors", [])))
Cập nhật: 30 tháng 9, 2026