Trình duyệt headless render JavaScript, nên chúng xử lý được các trang web hiện đại mà những HTTP client thông thường không làm được. Nhưng trình duyệt vẫn gửi mọi request từ một IP duy nhất, và automation bị phát hiện ngay khi một trang web giới hạn tốc độ (rate-limit) hoặc lấy fingerprint địa chỉ đó. Dùng proxy với Playwright và Puppeteer giúp phân tán lưu lượng qua nhiều IP, và nếu làm đúng, khiến automation của bạn trông như những người dùng bình thường. Dưới đây là cách thiết lập hoạt động được cho cả hai, bằng Python và Node.
Đặt proxy ngay khi khởi chạy trình duyệt. Truyền thông tin xác thực dưới dạng các trường username và password riêng biệt — đừng nhúng thông tin đăng nhập vào trong URL của server:
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://gate.jibaoproxy.com:10001",
"username": "USERNAME",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY, headless=True)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.inner_text("body"))
browser.close()
JIBAO cung cấp cả HTTP và SOCKS5 trên gateway. Hãy dùng endpoint HTTP cho browser automation: Playwright và Puppeteer không hỗ trợ proxy SOCKS5 có xác thực, nên HTTP-có-xác-thực là lựa chọn đáng tin cậy.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true,
proxy: {
server: 'http://gate.jibaoproxy.com:10001',
username: 'USERNAME',
password: 'PASSWORD',
},
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(await page.innerText('body'));
await browser.close();
})();
Cách luân chuyển sạch sẽ nhất trong Playwright là một IP cho mỗi BrowserContext. Mỗi context là một phiên cô lập (có cookie và cache riêng), nên việc gán mỗi context vào một exit IP khác nhau cho bạn nhiều danh tính song song từ một tiến trình trình duyệt duy nhất:
from playwright.sync_api import sync_playwright
def ctx_proxy(session_id):
return {
"server": "http://gate.jibaoproxy.com:10001",
"username": f"USERNAME-session-{session_id}",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
for i in range(3):
context = browser.new_context(proxy=ctx_proxy(f"ctx{i}"))
page = context.new_page()
page.goto("https://httpbin.org/ip")
print(i, page.inner_text("body"))
context.close()
browser.close()
Mỗi context dùng một token sticky session riêng biệt, nên IP giữ ổn định bên trong một context (tốt cho luồng đăng nhập) nhưng khác nhau giữa các context (tốt cho việc chạy nhiều tài khoản song song). Đây chính là kiểu mà các anti-detect browser như GoLogin và Dolphin Anty tự động hóa — xem hướng dẫn thiết lập proxy cho anti-detect của chúng tôi.
Puppeteer đặt proxy server làm cờ khởi chạy của Chromium, sau đó xác thực trên đối tượng page:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--proxy-server=http://gate.jibaoproxy.com:10001'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'USERNAME', password: 'PASSWORD' });
await page.goto('https://httpbin.org/ip');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
})();
Vì proxy là một cờ cấp tiến trình, một trình duyệt Puppeteer duy nhất dùng một IP. Để luân chuyển, hãy khởi chạy một trình duyệt mới cho mỗi danh tính (nặng hơn) hoặc điều khiển việc luân chuyển thông qua một gateway tự đổi IP theo từng kết nối.
Bất kỳ luồng nào tạo ra session cookie đều phải giữ cùng một IP trong suốt vòng đời của nó. Một cookie được tạo trên IP-A mà bỗng nhiên xuất hiện từ IP-B sẽ bị hiểu là chiếm phiên (session hijacking) và kích hoạt việc xác thực lại hoặc một lệnh cấm. Hãy giữ một context (hoặc một trình duyệt) cho mỗi tài khoản đã đăng nhập, gắn vào một token sticky session duy nhất, trong suốt toàn bộ phiên.
Một IP dân cư (residential) là cần thiết nhưng chưa đủ. Các trang web còn đọc cả handshake TLS/JA4 của trình duyệt bạn, thứ tự frame HTTP/2, canvas, WebGL, và các thuộc tính navigator. Chromium headless nguyên bản rò rỉ navigator.webdriver = true và một fingerprint headless đánh bại cả IP tốt nhất. Hãy giảm thiểu bằng các stealth plugin và các cờ khởi chạy thực tế:
// Node: puppeteer-extra + stealth
const puppeteer = require('puppeteer-extra');
const Stealth = require('puppeteer-extra-plugin-stealth');
puppeteer.use(Stealth());
// Realistic launch flags
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.jibaoproxy.com:10001',
'--disable-blink-features=AutomationControlled',
'--window-size=1920,1080',
],
});
Để xem chính xác bạn đang rò rỉ những tín hiệu nào, hãy chạy trình duyệt tự động hóa của bạn với công cụ kiểm tra fingerprint JA3/JA4 miễn phí của JIBAO. Để hiểu sâu hơn cơ chế vì sao handshake bị gắn cờ, hãy đọc vượt qua TLS fingerprinting và công thức bypass Cloudflare đầy đủ.
headless=False để quan sát mục tiêu thực sự hiển thị gì cho bot của bạn.Nhận 500MB lưu lượng miễn phí và các IP residential giúp Playwright và Puppeteer tránh khỏi danh sách cấm.
Bắt đầu Dùng thử Miễn phíNgười dùng mới nhận 500MB khi đăng ký, cùng tiền thưởng cho lần nạp đầu tiên. Ưu đãi có thời hạn.