Trình duyệt Headless là một trình duyệt không có giao diện người dùng đồ họa (GUI). Nó có thể chạy ngầm, cho phép lập trình viên điều khiển và thao tác trình duyệt thông qua giao diện dòng lệnh hoặc kịch bản.
Bây giờ là lúc để bắt đầu học cách phát hiện và chống phát hiện bot với Nstbrowser!
Headless Chrome là chế độ không giao diện của Google Chrome. Nó cho phép các nhà phát triển điều khiển và thao tác trình duyệt Chrome thông qua dòng lệnh hoặc kịch bản mà không cần hiển thị giao diện người dùng của trình duyệt. Headless Chrome kết hợp sức mạnh của Chrome với hiệu quả của chế độ không giao diện, làm cho nó trở thành một công cụ không thể thiếu cho phát triển web hiện đại và kiểm thử.
Thường bị chặn khi thu thập dữ liệu web?
Nstbrowser hoàn toàn mở khóa các trang web để tránh bị phát hiện
Thử miễn phí Nstbrowser ngay!
Bạn có suy nghĩ hoặc câu hỏi nào về việc thu thập dữ liệu web và Browseless không?
Hãy đến xem những gì các nhà phát triển khác đang chia sẻ trên Discord và Telegram!
Trình duyệt Headless cũng thường được sử dụng cho mục đích chống trình thu thập dữ liệu do tính tự động cao của chúng. Do đó, việc phát hiện sự hiện diện của nó trở nên rất quan trọng.
Dưới đây là một số cách phổ biến để phát hiện trình duyệt Headless bằng mã JavaScript làm ví dụ và một số phương pháp chống phát hiện:
User agent là một định danh mà trình duyệt gửi tới máy chủ. Bằng cách kiểm tra xem user agent có chứa từ “Headless” hay không, chúng ta có thể ban đầu xác định liệu yêu cầu đến từ Headless Chrome hay không. Phương pháp này thường không đáng tin cậy vì user agent có thể bị giả mạo hoặc chỉnh sửa.
const isHeadlessUserAgent = navigator.userAgent.toLowerCase().includes('headless');
// custom userAgent without 'headless'
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, như Gecko) Chrome/124.0.0.0 Safari/537.36'
});
Headless Chrome thường không thực thi JavaScript hoặc khả năng thực thi JavaScript của chúng yếu, do đó chúng ta có thể xác định liệu trình duyệt có hỗ trợ JavaScript hay không bằng cách thực thi một số mã JavaScript đơn giản. Điều này có thể được thực hiện bằng cách kiểm tra xem một số API hoặc hàm JavaScript nhất định có khả dụng hay không.
const isJavaScriptEnabled = typeof window !== 'undefined';
Một số tính năng của trình duyệt có thể bị vô hiệu hoặc hoạt động không bình thường trong Headless Chrome. Do đó, chúng ta có thể sử dụng các tính năng này để phát hiện. Ví dụ, API Canvas có thể được sử dụng để phát hiện.
const isCanvasSupported = () => {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
return !!context;
}
Phát hiện Headless Chrome có thể được thực hiện bằng cách kiểm tra sự hiện diện của thuộc tính navigator.webdriver
. Trình duyệt Headless thường thiết lập thuộc tính này, trong khi trình duyệt bình thường thì không. Nguồn liên quan: Chromium có thể xác định liệu đó có phải là Headless Chrome hay không.
const isWebDriverSupported = () => {
return navigator.webdriver;
}
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
window.chrome
Phát hiện sự hiện diện của window.chrome
có thể giúp xác định xem trình duyệt có ở chế độ headless hay không. Trong chế độ headless, thuộc tính này thường không tồn tại.
const isWindowChromeSupported = () => {
return window.chrome !== undefined;
}
WebRTC là một tiêu chuẩn web được sử dụng cho giao tiếp thời gian thực trong trình duyệt, và thêm chi tiết sẽ có trên trang web chính thức của Webrtc. Nói cách khác, Headless Chrome thường vô hiệu WebRTC, do đó bạn có thể xác định liệu trình duyệt có phải là headless hay không bằng cách kiểm tra khả dụng của WebRTC.
const isWebRTCSupported = () => {
return !!window.RTCPeerConnection;
}
Việc phát âm thanh hoặc video thường bị vô hiệu trong chế độ headless. Bằng cách thử phát âm thanh hoặc video, chúng ta có thể dễ dàng phát hiện liệu trình duyệt có phải là headless hay không.
const isAudioVideoSupported = () => {
const audio = document.createElement('audio');
const video = document.createElement('video');
return !!(audio.canPlayType && video.canPlayType);
}
Hiện tại, Headless Chrome không thể thao tác các quyền của trình duyệt, vì vậy chúng không hỗ trợ Notification.permission
. Chúng không xử lý các sự kiện giao diện người dùng, chỉ tải và hiển thị trang, vì vậy trong headlesschrome, Notification.permission
và navigator.permissions.query
không khớp nhau.
const isHeadlessPermissionMatched = () => {
return navigator.permissions.query({name: 'notifications'})
.then(permissionStatus => {
return Notification.permission === 'denied' && permissionStatus.state === 'prompt';
})
.catch(() => {
return false;
});
};
navigator.plugins
navigator.plugins
có thể tìm ra danh sách các plugin hiện có trong trình duyệt. Các trình duyệt bình thường sẽ cài đặt một số plugin mặc định như: Chrome PDF viewer hoặc Google Native Client, v.v., nhưng trong chế độ headless thường không có bất kỳ plugin nào. Vì vậy, bạn có thể xác định liệu đó có phải là trình duyệt headless bằng cách kiểm tra danh sách plugin.
const pluginInstalled = () => {
return navigator.plugins.length > 0
}
const originalPlugins = navigator.plugins;
Object.defineProperty(navigator, 'plugins', {
get: () => originalPlugins
});
Trong Chrome, ngôn ngữ mà người dùng sử dụng có thể được lấy thông qua navigator.language
và navigator.languages
, cái trước là ngôn ngữ của giao diện người dùng trình duyệt và cái sau là danh sách các ngôn ngữ ưa thích của người dùng. Trong headlesschrome, navigator.languages
sẽ trả về một chuỗi trống.
const isHeadlessLanguage = () => {
return !navigator.languages || navigator.languages.length === 0
}
Object.defineProperty(navigator, 'languages', {
value: ['en-US', 'en']
});
Phương pháp phát hiện:
Các phương pháp chống phát hiện:
Điều quan trọng cần lưu ý là vì trình duyệt không đầu có thể mô phỏng hành vi của hầu hết các trình duyệt thông thường, và sẽ sử dụng nhiều phương pháp chống phát hiện để làm cho Headless Chrome giống với hành vi của người dùng thực, làm cho việc chống phát hiện trở nên khó khăn hơn. Vì vậy, dù sử dụng phương pháp nào để chống phát hiện trình duyệt không đầu, chúng không hoàn toàn đáng tin cậy, ít nhất là cho đến hiện tại.
Chúng ta cũng có thể sử dụng fingerprint browser để vượt qua phát hiện Headless Chrome. Hãy lấy trình duyệt chống phát hiện Nstbrowser làm ví dụ. Giải pháp API của Nstbrowser là một trong những lựa chọn tốt nhất để tránh phát hiện bot hiện nay. Bạn có thể sử dụng nó và nhận API key miễn phí.
Tiếp theo, chúng tôi sẽ so sánh hiệu quả của việc phát hiện trình duyệt không đầu bằng cách truy cập các trang web phát hiện headlesschrome CreepJS và Areyouheadless thông qua trình duyệt chống dấu vân tay Nstbrowser và trình duyệt GoogleChrome cục bộ của tôi, tương ứng.
Chúng tôi sẽ sử dụng API gọi Puppeteer để khởi chạy trình duyệt không dấu vân tay, cụ thể là chúng tôi sẽ sử dụng giao diện LaunchExistBrowser
, nhưng tất nhiên bạn có thể chọn bất kỳ API nào khác bạn cần dựa trên tài liệu.
Trước khi bạn bắt đầu, bạn cần:
Khi mọi thứ đã sẵn sàng, đã đến lúc lập trình. Mã sau đây cho thấy việc bắt đầu trình duyệt ở Chế độ không đầu và truy cập trang Kiểm tra Trình duyệt Không đầu và chụp ảnh màn hình:
import puppeteer from 'puppeteer-core';
// wiat for millseconds
function sleep(millseconds) {
return new Promise(resolve => setTimeout(resolve, millseconds));
}
// visit headless detection site and take screenshots
async function execPuppeteer(browserWSEndpoint) {
try {
const browser = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint,
defaultViewport: null,
});
const page = await browser.newPage();
// detect headless on creepjs site
await page.goto('https://abrahamjuliot.github.io/creepjs');
await sleep(5 * 1000);
await page.screenshot({ fullPage: true, path: 'detect_headless_creepjs.png' });
// detect headless on areyouheadless site
await page.goto('https://arh.antoinevastel.com/bots/areyouheadless');
await sleep(2 * 1000);
await page.screenshot({ path: 'detect_headless_areyouheadless.png' });
await page.close();
await browser.disconnect();
} catch (err) {
console.error(err);
}
}
// LaunchExistBrowser: Connect to or start an existing browser
// You need to create the corresponding profile in advance
// Support custom config
async function launchAndConnectToBrowser(profileId) {
const host = 'localhost:8848';
const apiKey = 'you api key;
const config = {
headless: true, // support: true, 'new'
autoClose: true,
};
const query = new URLSearchParams({
'x-api-key': apiKey, // required
config: encodeURIComponent(JSON.stringify((config))),
});
const browserWSEndpoint = `ws://${host}/devtool/launch/${profileId}?${query.toString()}`;
console.log('browserWSEndpoint: ', browserWSEndpoint);
await execPuppeteer(browserWSEndpoint);
}
launchAndConnectToBrowser('your profile id').then();
So sánh ảnh chụp màn hình của kết quả với kết quả Google Chrome cục bộ của tôi, chúng tôi nhận thấy rằng việc phát hiện trình duyệt không đầu trên cả hai trang web đều không nhận ra rằng chúng tôi đang sử dụng trình duyệt không đầu, điều mà chúng tôi mong muốn.
Thông qua thảo luận và mã mẫu trong bài viết này, chúng tôi hy vọng cung cấp cho các nhà phát triển tài liệu tham khảo và hướng dẫn hiệu quả để cải thiện tính bảo mật của trang web và khả năng bảo vệ dữ liệu.
Việc phát hiện và chống phát hiện trình duyệt không đầu là một quá trình tiến hóa của sự đối đầu công nghệ. Nguy cơ bị phát hiện và chặn có thể được khắc phục bằng cách sử dụng các công cụ chống phát hiện hiệu quả. Nstbrowser có thể giúp bạn đảm bảo hoàn toàn không bị phát hiện và sử dụng công nghệ tiên tiến để mở khóa mạng chặn.
Ngoài ra, các nhà phát triển cần chú ý đến các tiến bộ công nghệ mới nhất và cập nhật các chiến lược phát hiện của họ để đáp ứng các thách thức mới. Bất kỳ phương pháp nào được sử dụng để chống phát hiện headlesschrome đều cần được tối ưu hóa và cải tiến liên tục để đảm bảo tính hiệu quả và độ tin cậy của nó.