Bị phát hiện headless browser: nguyên nhân và cách khắc phục (2026)
Trang web báo "headless browser detected", hoặc âm thầm trả về một trang khác cho trình duyệt tự động của bạn. Trang làm vậy vì headless browser chạy không có cửa sổ và thường khác trình duyệt desktop thông thường ở vài điểm nhỏ, đo được. Hướng dẫn này giải thích trang nhìn vào tín hiệu nào, cách kiểm tra trình duyệt của bạn đang lộ ra điều gì, và một cách sửa hợp lý trông như thế nào. Nó cũng nói về thời điểm đúng là nên dừng lại, hoặc coi bước kiểm tra đó như một bước captcha.
Vì sao trang kiểm tra headless browser
Các framework tự động hóa điều khiển một động cơ trình duyệt thật, nên phần lớn trang hoạt động giống nhau. Khác biệt xuất hiện ở các cạnh:
- Cờ tự động hóa. Trình duyệt được điều khiển bằng công cụ tự động hóa từng để lộ thuộc tính
navigator.webdrivervới giá trịtrue, và một số framework để lại dấu vết khác trong trang. - Thiếu hoặc lạ ở tính năng trình duyệt. Bản headless có thể không báo plugin nào, danh sách ngôn ngữ bất thường, hoặc kích thước cửa sổ không khớp màn hình thật.
- Khác biệt khi render. Đầu ra canvas và WebGL có thể khác giữa môi trường headless và có giao diện, nhất là trên server không có GPU.
- Thời gian. Thao tác click và tải trang tự động thường có nhịp mà không người nào tạo ra.
- Hành vi mạng. Header request, thứ tự của chúng và bắt tay TLS có thể để lộ một client không phải trình duyệt.
Trang kết hợp các tín hiệu này thành một điểm số. Điểm thấp có thể dẫn tới việc hạ cấp âm thầm, thêm một loạt kiểm tra, hoặc chặn.
Bước 1: xem trình duyệt của bạn để lộ gì
Trước khi thay đổi gì, hãy xem trang có thể đọc được gì từ tự động hóa của bạn. Đoạn script dưới đây mở một trang bạn kiểm soát và in ra các tín hiệu quan trọng. Đây là công cụ chẩn đoán: chỉ dùng trên trang thử nghiệm của bạn, không dùng để dò hệ thống của người khác.
from playwright.sync_api import sync_playwright
CHECK = """() => ({
webdriver: navigator.webdriver,
languages: navigator.languages,
plugins: navigator.plugins.length,
userAgent: navigator.userAgent,
screen: [screen.width, screen.height],
viewport: [window.innerWidth, window.innerHeight],
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
})"""
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com") # thay bằng một trang bạn sở hữu
print(page.evaluate(CHECK))
browser.close()
Chạy lại cùng script với headless=False, rồi so sánh hai kết quả. Những khác biệt chính là những thứ trang có thể nhận ra.
Bước 2: sửa sự không nhất quán, không chỉ che cờ
Che một cờ trong khi giữ nguyên các cờ khác là sai lầm phổ biến nhất. User agent nói Windows trong khi font, múi giờ và kích thước màn hình mô tả một server Linux là tín hiệu mạnh hơn nhiều so với một thuộc tính đơn lẻ. Hãy nhắm tới một môi trường nhất quán bên trong:
- Dùng trình duyệt có giao diện khi có thể, hoặc chế độ headless khớp với một trình duyệt desktop hiện đại.
- Đặt viewport và ngôn ngữ khớp nhau.
- Giữ múi giờ và locale phù hợp với địa chỉ IP bạn dùng.
- Dùng lại một profile và cookie của nó cho một danh tính, thay vì bắt đầu mới ở mỗi lần chạy.
Playwright cho phép bạn đặt nhiều thứ trong số này ở một chỗ:
context = browser.new_context(
locale="en-US",
timezone_id="America/New_York",
viewport={"width": 1366, "height": 768},
)
page = context.new_page()
Bước 3: chậm lại và hành xử như một khách truy cập
Tự động hóa lộ rõ khi nó nhanh hơn người có thể làm. Thêm khoảng nghỉ thực tế giữa các lần tải trang, tránh click vào cùng một phần tử theo nhịp hoàn hảo, và đừng mở hàng trăm trang song song từ cùng một địa chỉ. Gửi ít request hơn và chậm hơn cũng làm giảm tải cho trang, và đó vốn là điều đúng đắn phải làm.
Bước 4: biết khi nào kiểm tra là captcha
Một số luồng phát hiện kết thúc bằng thử thách thay vì chặn. Bạn sẽ thấy một widget captcha, và bước đó cần một token từ bộ giải. Loại captcha đang hoạt động trên Scarnox hiện nay là PopularCaptcha. Hướng dẫn Python cho PopularCaptcha chỉ cách token được yêu cầu và gửi đi. Các widget khác, như Cloudflare Turnstile, nằm trong lộ trình nhưng chưa hoạt động, nên hãy xem các loại captcha được giải thích trước khi lên kế hoạch dựa vào một loại nào đó.
Một bước captcha không có nghĩa là phần còn lại của thiết lập của bạn đã ổn. Nếu cùng một trang chặn mọi phiên headless dù bạn cấu hình thế nào, đó là tín hiệu rõ ràng rằng chủ sở hữu không muốn truy cập tự động. Hãy tôn trọng điều đó.
Những việc không nên làm
Đừng cố che giấu tự động hóa khỏi một trang cấm điều đó, và đừng dùng công cụ né tránh phát hiện để vượt qua các kiểm soát truy cập. Đó là một loại dự án khác với việc thử nghiệm và thu thập dữ liệu công khai mà hướng dẫn này đề cập. Nếu dự án của bạn cần quyền truy cập mà bạn chưa được cấp, hãy hỏi chủ trang hoặc tìm API chính thức hay nguồn dữ liệu chính thức.
Scrape có trách nhiệm
- Kiểm tra
robots.txtvà điều khoản của trang trước khi tự động hóa. - Giữ tốc độ request thấp, và lưu đệm các trang bạn đã tải.
- Coi một lần bị chặn là câu trả lời, không phải một câu đố cần tìm cách vượt qua.
- Không thu thập dữ liệu cá nhân nếu không có cơ sở pháp lý.
Đọc tiếp
Nếu tự động hóa của bạn phục vụ kiểm thử end-to-end, cách làm khác: xem captcha trong kiểm thử tự động. Nếu bạn đang chạy thiết lập Playwright hoặc Puppeteer, xử lý captcha với Playwright và Puppeteer giải thích token đi vào đâu.
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 trang của chính bạn. Xem giá hiện tại tại trang giá.