Puppeteer và Playwright là những công cụ phổ biến để tự động hóa trình duyệt và thu thập dữ liệu web. Khi làm việc với khối lượng lớn yêu cầu hoặc phân tích các trang web bảo mật, việc sử dụng proxy trở nên cực kỳ quan trọng để tránh bị chặn theo IP. Trong hướng dẫn này, chúng ta sẽ xem xét tất cả các cách tích hợp proxy vào cả hai công cụ, từ cài đặt cơ bản đến các kịch bản nâng cao với xoay vòng và xử lý lỗi.
Cơ bản về hoạt động của proxy trong trình duyệt headless
Puppeteer và Playwright điều khiển các trình duyệt thực (Chromium, Firefox, WebKit) thông qua DevTools Protocol. Điều này có nghĩa là proxy được cấu hình ở cấp độ khởi động trình duyệt, chứ không phải là các yêu cầu riêng lẻ. Cả hai công cụ đều hỗ trợ proxy HTTP, HTTPS và SOCKS5, nhưng có các API khác nhau để cấu hình chúng.
Những điểm khác biệt chính so với các thư viện HTTP thông thường (axios, fetch):
- Proxy được thiết lập khi khởi động trình duyệt — không thể thay đổi proxy trong một phiên trình duyệt
- Hỗ trợ JavaScript và kết xuất — proxy được áp dụng cho tất cả các tài nguyên của trang (hình ảnh, script, XHR)
- Xử lý tự động chuyển hướng và cookies — trình duyệt hoạt động như một người dùng thực sự
- Fingerprinting — ngay cả với proxy, các trang web có thể xác định tự động hóa dựa trên các đặc điểm của trình duyệt
Quan trọng: Đối với các nhiệm vụ yêu cầu thay đổi IP thường xuyên (phân tích hàng ngàn trang, đăng ký hàng loạt), hiệu quả hơn khi sử dụng proxy dân cư với xoay vòng — chúng cho phép thay đổi IP cho mỗi yêu cầu mà không cần khởi động lại trình duyệt.
Cài đặt proxy trong Puppeteer
Puppeteer là thư viện của Google để quản lý Chrome/Chromium. Proxy được cấu hình thông qua các đối số khởi động trình duyệt bằng cách sử dụng cờ --proxy-server.
Cài đặt cơ bản cho proxy HTTP/HTTPS
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: true,
args: [
'--proxy-server=http://proxy.example.com:8080'
]
});
const page = await browser.newPage();
// Kiểm tra địa chỉ IP
await page.goto('https://api.ipify.org?format=json');
const content = await page.content();
console.log('Địa chỉ IP hiện tại:', content);
await browser.close();
})();
Mã này khởi động trình duyệt thông qua máy chủ proxy. Tất cả các yêu cầu HTTP và HTTPS sẽ đi qua proxy đã chỉ định. Để kiểm tra tính khả dụng, dịch vụ ipify được sử dụng, trả về địa chỉ IP bên ngoài.
Cài đặt proxy SOCKS5
const browser = await puppeteer.launch({
headless: true,
args: [
'--proxy-server=socks5://proxy.example.com:1080'
]
});
// Mã còn lại tương tự
Proxy SOCKS5 hoạt động ở cấp độ thấp hơn và hỗ trợ lưu lượng UDP, điều này có thể hữu ích cho một số ứng dụng web. Cú pháp giống như proxy HTTP, chỉ thay đổi giao thức trong URL.
Sử dụng proxy cho các miền cụ thể
const browser = await puppeteer.launch({
args: [
'--proxy-server=http://proxy1.example.com:8080',
'--proxy-bypass-list=localhost;127.0.0.1;*.internal.com'
]
});
// Các yêu cầu cục bộ và yêu cầu đến *.internal.com sẽ đi trực tiếp
// Tất cả các yêu cầu khác — qua proxy
Cờ --proxy-bypass-list cho phép loại trừ các miền cụ thể khỏi việc sử dụng proxy. Điều này hữu ích khi cần kết hợp các yêu cầu trực tiếp và yêu cầu qua proxy.
Cài đặt proxy trong Playwright
Playwright là thư viện hiện đại hơn của Microsoft, hỗ trợ Chromium, Firefox và WebKit. Proxy được cấu hình thông qua đối tượng cấu hình, điều này làm cho API dễ hiểu và kiểu hóa hơn.
Cài đặt cơ bản cho proxy
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080'
}
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://api.ipify.org?format=json');
const ip = await page.textContent('body');
console.log('IP qua proxy:', ip);
await browser.close();
})();
Playwright sử dụng đối tượng proxy thay vì các đối số dòng lệnh. Điều này đảm bảo kiểu hóa tốt hơn trong TypeScript và mã sạch hơn.
Cài đặt proxy ở cấp độ ngữ cảnh
const browser = await chromium.launch();
// Ngữ cảnh 1 - với proxy
const context1 = await browser.newContext({
proxy: {
server: 'http://proxy1.example.com:8080'
}
});
// Ngữ cảnh 2 - với proxy khác
const context2 = await browser.newContext({
proxy: {
server: 'http://proxy2.example.com:8080'
}
});
const page1 = await context1.newPage();
const page2 = await context2.newPage();
// Mỗi trang sử dụng proxy riêng của mình!
Một trong những lợi thế chính của Playwright là khả năng tạo nhiều ngữ cảnh trình duyệt với các proxy khác nhau trong cùng một quy trình. Điều này tiết kiệm tài nguyên khi làm việc với nhiều địa chỉ IP.
Loại trừ các miền khỏi việc sử dụng proxy
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080',
bypass: 'localhost,127.0.0.1,*.internal.com'
}
});
// Các yêu cầu đến localhost và *.internal.com sẽ đi trực tiếp
Xác thực bằng tên đăng nhập và mật khẩu
Hầu hết các proxy thương mại yêu cầu xác thực. Cả hai công cụ đều hỗ trợ xác thực, nhưng thực hiện nó theo cách khác nhau.
Xác thực trong Puppeteer
const browser = await puppeteer.launch({
args: ['--proxy-server=http://proxy.example.com:8080']
});
const page = await browser.newPage();
// Thiết lập thông tin xác thực cho proxy
await page.authenticate({
username: 'your_username',
password: 'your_password'
});
await page.goto('https://httpbin.org/ip');
const content = await page.content();
console.log(content);
Phương thức page.authenticate() thiết lập thông tin xác thực cho tất cả các yêu cầu tiếp theo trên trang này. Quan trọng là gọi nó TRƯỚC khi gọi page.goto() đầu tiên.
Xác thực trong Playwright
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080',
username: 'your_username',
password: 'your_password'
}
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
Playwright cho phép chỉ định thông tin xác thực ngay trong đối tượng cấu hình proxy — điều này thuận tiện và an toàn hơn, vì không yêu cầu gọi thêm các phương thức.
Cách thay thế: thông tin xác thực trong URL
// Hoạt động trong cả hai framework
const proxyUrl = 'http://username:password@proxy.example.com:8080';
// Puppeteer
const browser = await puppeteer.launch({
args: [`--proxy-server=${proxyUrl}`]
});
// Playwright
const browser = await chromium.launch({
proxy: { server: proxyUrl }
});
Cách này hoạt động, nhưng không được khuyến nghị cho sản xuất — thông tin xác thực có thể bị ghi vào nhật ký. Sử dụng biến môi trường để lưu trữ dữ liệu nhạy cảm.
Mẹo: Khi làm việc với việc phân tích các trang web thương mại, chúng tôi khuyên bạn nên sử dụng proxy dân cư — chúng có địa chỉ IP thực của người dùng gia đình và ít bị chặn bởi các hệ thống chống bot hơn.
Xoay vòng proxy và quản lý pool IP
Để phân tích quy mô lớn, cần thường xuyên thay đổi địa chỉ IP. Vì proxy được thiết lập khi khởi động trình duyệt, việc xoay vòng yêu cầu khởi động lại phiên trình duyệt.
Xoay vòng đơn giản với mảng proxy (Puppeteer)
const puppeteer = require('puppeteer');
const proxyList = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080'
];
async function scrapeWithRotation(urls) {
for (let i = 0; i < urls.length; i++) {
const proxyUrl = proxyList[i % proxyList.length];
const browser = await puppeteer.launch({
args: [`--proxy-server=${proxyUrl}`]
});
try {
const page = await browser.newPage();
await page.goto(urls[i], { waitUntil: 'networkidle0' });
const data = await page.evaluate(() => {
return {
title: document.title,
url: window.location.href
};
});
console.log(`URL ${i + 1}:`, data);
} catch (error) {
console.error(`Lỗi tại ${urls[i]}:`, error.message);
} finally {
await browser.close();
}
}
}
const urlsToScrape = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3',
'https://example.com/page4'
];
scrapeWithRotation(urlsToScrape);
Mã này lặp qua các proxy trong danh sách và khởi động một trình duyệt mới cho mỗi URL. Phương thức i % proxyList.length đảm bảo xoay vòng theo chu kỳ.
Xoay vòng với pool ngữ cảnh (Playwright)
const { chromium } = require('playwright');
const proxyList = [
{ server: 'http://proxy1.example.com:8080', username: 'user1', password: 'pass1' },
{ server: 'http://proxy2.example.com:8080', username: 'user2', password: 'pass2' },
{ server: 'http://proxy3.example.com:8080', username: 'user3', password: 'pass3' }
];
async function scrapeWithContextPool(urls) {
const browser = await chromium.launch();
// Tạo pool ngữ cảnh với các proxy khác nhau
const contexts = await Promise.all(
proxyList.map(proxy => browser.newContext({ proxy }))
);
for (let i = 0; i < urls.length; i++) {
const context = contexts[i % contexts.length];
const page = await context.newPage();
try {
await page.goto(urls[i], { waitUntil: 'networkidle' });
const title = await page.title();
console.log(`URL ${i + 1} (proxy ${i % contexts.length}):`, title);
} catch (error) {
console.error(`Lỗi tại ${urls[i]}:`, error.message);
} finally {
await page.close();
}
}
await browser.close();
}
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3'
];
scrapeWithContextPool(urls);
Playwright cho phép tạo nhiều ngữ cảnh trong một trình duyệt, mỗi ngữ cảnh với proxy riêng của nó. Điều này tiết kiệm bộ nhớ và thời gian khởi động so với việc khởi động lại toàn bộ trình duyệt.
Xoay vòng thông minh với theo dõi lỗi
class ProxyRotator {
constructor(proxyList) {
this.proxyList = proxyList;
this.currentIndex = 0;
this.failedProxies = new Set();
}
getNext() {
const availableProxies = this.proxyList.filter(
(_, index) => !this.failedProxies.has(index)
);
if (availableProxies.length === 0) {
throw new Error('Tất cả các proxy đều không khả dụng');
}
const proxy = this.proxyList[this.currentIndex];
this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
return { proxy, index: this.currentIndex - 1 };
}
markFailed(index) {
this.failedProxies.add(index);
console.log(`Proxy ${index} đã được đánh dấu là không khả dụng`);
}
resetFailed() {
this.failedProxies.clear();
}
}
// Sử dụng
const rotator = new ProxyRotator(proxyList);
async function scrapeWithSmartRotation(url, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const { proxy, index } = rotator.getNext();
const browser = await chromium.launch({ proxy });
const page = await browser.newPage();
try {
await page.goto(url, { timeout: 30000 });
const data = await page.content();
await browser.close();
return data;
} catch (error) {
console.error(`Lỗi với proxy ${index}:`, error.message);
rotator.markFailed(index);
await browser.close();
if (attempt === maxRetries - 1) {
throw new Error(`Không thể tải ${url} sau ${maxRetries} lần thử`);
}
}
}
}
Lớp này theo dõi các proxy không hoạt động và loại trừ chúng khỏi việc xoay vòng. Khi có lỗi, nó tự động chuyển sang proxy tiếp theo trong danh sách.
Xử lý lỗi và kiểm tra tính khả dụng
Khi làm việc với proxy, có những lỗi đặc thù xảy ra: thời gian chờ kết nối, từ chối xác thực, chặn IP bởi trang web mục tiêu. Việc xử lý lỗi đúng cách là rất quan trọng để đảm bảo hoạt động ổn định của trình thu thập dữ liệu.
Các lỗi điển hình và cách xử lý
async function safePageLoad(page, url, options = {}) {
const defaultOptions = {
timeout: 30000,
waitUntil: 'networkidle0',
maxRetries: 3,
retryDelay: 2000
};
const config = { ...defaultOptions, ...options };
for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
try {
await page.goto(url, {
timeout: config.timeout,
waitUntil: config.waitUntil
});
return { success: true, attempt };
} catch (error) {
console.error(`Lần thử ${attempt} không thành công:`, error.message);
// Phân tích loại lỗi
if (error.message.includes('ERR_PROXY_CONNECTION_FAILED')) {
throw new Error('Proxy không khả dụng');
}
if (error.message.includes('ERR_TUNNEL_CONNECTION_FAILED')) {
throw new Error('Lỗi tunneling proxy');
}
if (error.message.includes('407')) {
throw new Error('Lỗi xác thực proxy (407)');
}
if (error.message.includes('Navigation timeout')) {
console.log(`Thời gian tải đã hết, thử lại sau ${config.retryDelay}ms`);
await new Promise(resolve => setTimeout(resolve, config.retryDelay));
continue;
}
// Nếu đây là lần thử cuối cùng - ném lỗi
if (attempt === config.maxRetries) {
throw error;
}
}
}
}
Kiểm tra tính khả dụng của proxy
async function testProxy(proxyConfig) {
const browser = await chromium.launch({ proxy: proxyConfig });
const page = await browser.newPage();
const result = {
working: false,
ip: null,
responseTime: null,
error: null
};
const startTime = Date.now();
try {
await page.goto('https://api.ipify.org?format=json', { timeout: 10000 });
const content = await page.textContent('body');
const data = JSON.parse(content);
result.working = true;
result.ip = data.ip;
result.responseTime = Date.now() - startTime;
} catch (error) {
result.error = error.message;
} finally {
await browser.close();
}
return result;
}
// Kiểm tra danh sách proxy
async function validateProxyList(proxyList) {
console.log('Đang kiểm tra proxy...');
const results = await Promise.all(
proxyList.map(async (proxy, index) => {
const result = await testProxy(proxy);
console.log(`Proxy ${index + 1}:`, result.working ? `✓ ${result.ip} (${result.responseTime}ms)` : `✗ ${result.error}`);
return { proxy, ...result };
})
);
const workingProxies = results.filter(r => r.working);
console.log(`\nSố proxy hoạt động: ${workingProxies.length}/${proxyList.length}`);
return workingProxies.map(r => r.proxy);
}
Hàm này kiểm tra từng proxy trước khi sử dụng, đo thời gian phản hồi và chỉ trả về các proxy hoạt động. Khuyến nghị chạy xác thực khi khởi động ứng dụng.
Giám sát và ghi nhật ký
class ProxyMonitor {
constructor() {
this.stats = {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
proxyErrors: 0,
averageResponseTime: 0,
requestsByProxy: new Map()
};
}
recordRequest(proxyIndex, success, responseTime, error = null) {
this.stats.totalRequests++;
if (success) {
this.stats.successfulRequests++;
this.stats.averageResponseTime =
(this.stats.averageResponseTime * (this.stats.successfulRequests - 1) + responseTime) /
this.stats.successfulRequests;
} else {
this.stats.failedRequests++;
if (error && error.includes('proxy')) {
this.stats.proxyErrors++;
}
}
// Thống kê theo từng proxy
if (!this.stats.requestsByProxy.has(proxyIndex)) {
this.stats.requestsByProxy.set(proxyIndex, { success: 0, failed: 0 });
}
const proxyStats = this.stats.requestsByProxy.get(proxyIndex);
success ? proxyStats.success++ : proxyStats.failed++;
}
getReport() {
const successRate = (this.stats.successfulRequests / this.stats.totalRequests * 100).toFixed(2);
return {
...this.stats,
successRate: `${successRate}%`,
averageResponseTime: `${this.stats.averageResponseTime.toFixed(0)}ms`
};
}
}
// Sử dụng
const monitor = new ProxyMonitor();
async function monitoredScrape(url, proxyIndex) {
const startTime = Date.now();
try {
// ... mã phân tích ...
const responseTime = Date.now() - startTime;
monitor.recordRequest(proxyIndex, true, responseTime);
} catch (error) {
monitor.recordRequest(proxyIndex, false, 0, error.message);
throw error;
}
}
Các kịch bản nâng cao: định vị địa lý và fingerprinting
Các hệ thống chống bot hiện đại không chỉ kiểm tra địa chỉ IP mà còn kiểm tra sự phù hợp của định vị địa lý, múi giờ, ngôn ngữ trình duyệt và các tham số khác. Khi sử dụng proxy từ một quốc gia khác, điều quan trọng là phải cấu hình tất cả các tham số này một cách chính xác.
Cài đặt định vị địa lý và ngôn ngữ cho proxy
const { chromium } = require('playwright');
async function createContextWithGeo(proxy, geoData) {
const browser = await chromium.launch({ proxy });
const context = await browser.newContext({
locale: geoData.locale, // 'en-US', 'de-DE', 'fr-FR'
timezoneId: geoData.timezone, // 'America/New_York', 'Europe/Berlin'
geolocation: {
latitude: geoData.latitude,
longitude: geoData.longitude
},
permissions: ['geolocation']
});
return { browser, context };
}
// Ví dụ: proxy từ Đức
const germanyProxy = {
server: 'http://de-proxy.example.com:8080',
username: 'user',
password: 'pass'
};
const germanyGeo = {
locale: 'de-DE',
timezone: 'Europe/Berlin',
latitude: 52.520008,
longitude: 13.404954
};
const { browser, context } = await createContextWithGeo(germanyProxy, germanyGeo);
const page = await context.newPage();
await page.goto('https://www.google.com');
// Google sẽ hiển thị phiên bản tiếng Đức với kết quả cho Berlin
Mã này cấu hình trình duyệt để trông giống như một người dùng thực sự từ Đức: ngôn ngữ giao diện tiếng Đức, múi giờ Berlin và tọa độ trung tâm Berlin.
Cấu hình đầy đủ fingerprint
async function createStealthContext(proxy, profile) {
const context = await chromium.launch({ proxy }).then(b =>
b.newContext({
locale: profile.locale,
timezoneId: profile.timezone,
userAgent: profile.userAgent,
viewport: profile.viewport,
deviceScaleFactor: profile.deviceScaleFactor,
isMobile: profile.isMobile,
hasTouch: profile.hasTouch,
colorScheme: profile.colorScheme,
geolocation: profile.geolocation,
permissions: ['geolocation']
})
);
return context;
}
// Hồ sơ cho Windows 10 + Chrome từ Mỹ
const desktopUSProfile = {
locale: 'en-US',
timezone: 'America/New_York',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
viewport: { width: 1920, height: 1080 },
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
colorScheme: 'light',
geolocation: { latitude: 40.7128, longitude: -74.0060 }
};
// Hồ sơ cho iPhone từ Vương quốc Anh
const mobileUKProfile = {
locale: 'en-GB',
timezone: 'Europe/London',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
viewport: { width: 390, height: 844 },
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
colorScheme: 'light',
geolocation: { latitude: 51.5074, longitude: -0.1278 }
};
Cấu hình toàn diện fingerprint giảm khả năng phát hiện tự động hóa. Điều quan trọng là tất cả các tham số phải phù hợp với nhau: ví dụ, User-Agent di động phải đi kèm với độ phân giải màn hình di động.
Quan trọng: Khi làm việc với các nền tảng quảng cáo (Google Ads, Facebook Ads) hoặc dịch vụ tài chính, chúng tôi khuyên bạn nên sử dụng proxy di động — chúng có trust score của các nhà mạng di động thực và gần như không bị chặn.
Vượt qua WebRTC leak
// Puppeteer: chặn WebRTC
const browser = await puppeteer.launch({
args: [
'--proxy-server=http://proxy.example.com:8080',
'--disable-webrtc',
'--disable-webrtc-hw-encoding',
'--disable-webrtc-hw-decoding'
]
});
// Playwright: ghi đè API WebRTC
const context = await browser.newContext({ proxy: proxyConfig });
await context.addInitScript(() => {
// Chặn RTCPeerConnection
window.RTCPeerConnection = undefined;
window.RTCDataChannel = undefined;
window.RTCSessionDescription = undefined;
// Ghi đè getUserMedia
navigator.mediaDevices.getUserMedia = undefined;
navigator.getUserMedia = undefined;
});
WebRTC có thể tiết lộ địa chỉ IP thực của bạn ngay cả khi sử dụng proxy. Mã này hoàn toàn tắt API WebRTC trong trình duyệt.
So sánh Puppeteer và Playwright cho việc làm việc với proxy
| Tiêu chí | Puppeteer | Playwright |
|---|---|---|
| Cài đặt proxy | Thông qua args dòng lệnh | Thông qua đối tượng cấu hình |
| Xác thực | page.authenticate() sau khi khởi động | Trong đối tượng proxy khi tạo |
| Nhiều proxy trong một trình duyệt | Không, cần trình duyệt riêng | Có, thông qua các ngữ cảnh khác nhau |
| Hỗ trợ trình duyệt | Chỉ Chromium/Chrome | Chromium, Firefox, WebKit |
| Hiệu suất | Khởi động nhanh một trình duyệt | Hiệu quả hơn khi có nhiều ngữ cảnh |
| TypeScript | Kiểu qua @types/puppeteer | Hỗ trợ TypeScript tích hợp |
| Tài liệu | Tốt, nhiều ví dụ | Tuyệt vời, có cấu trúc hơn |
| Hệ sinh thái | Nhiều plugin và mở rộng hơn | Phát triển nhanh hơn, các tính năng mới |
Khuyến nghị khi lựa chọn
Chọn Puppeteer nếu:
- Bạn chỉ làm việc với Chrome/Chromium
- Bạn sử dụng một proxy tại một thời điểm
- Bạn cần tính tương thích tối đa với các công cụ hiện có
- Bạn đã có một mã nguồn lớn trên Puppeteer
Chọn Playwright nếu:
- Bạn cần làm việc với Firefox hoặc Safari (WebKit)
- Bạn cần sử dụng đồng thời nhiều proxy
- Bạn quan tâm đến hiệu suất khi mở rộng
- Bạn viết bằng TypeScript
- Bạn bắt đầu một dự án mới từ đầu
Hiệu suất khi xoay vòng proxy
Thử nghiệm: phân tích 100 trang với xoay vòng 10 proxy trên MacBook Pro M1:
| Phương pháp | Thời gian thực hiện | Tiêu thụ RAM |
|---|---|---|
| Puppeteer (khởi động lại trình duyệt) | 8 phút 23 giây | ~1.2 GB đỉnh |
| Playwright (khởi động lại trình duyệt) | 7 phút 54 giây | ~1.1 GB đỉnh |
| Playwright (pool ngữ cảnh) | 4 phút 12 giây | ~800 MB ổn định |
Playwright với pool ngữ cảnh nhanh gấp gần 2 lần nhờ không có chi phí khởi động trình duyệt. Điều này rất quan trọng khi phân tích hàng ngàn trang.
Kết luận
Tích hợp proxy với Puppeteer và Playwright là một thực tiễn tiêu chuẩn cho việc thu thập dữ liệu web, kiểm thử và tự động hóa. Puppeteer cung cấp sự đơn giản và hệ sinh thái rộng lớn, trong khi Playwright mang đến API hiện đại và hiệu suất tốt hơn khi làm việc với nhiều proxy thông qua các ngữ cảnh trình duyệt.
Những điểm chính mà chúng ta đã xem xét:
- Cài đặt cơ bản cho proxy HTTP, HTTPS và SOCKS5 trong cả hai framework
- Xác thực bằng tên đăng nhập và mật khẩu
- Xoay vòng proxy cho việc phân tích quy mô lớn
- Xử lý lỗi và xác thực proxy trước khi sử dụng
- Cấu hình định vị địa lý và fingerprint để vượt qua các hệ thống chống bot
- So sánh hiệu suất của các phương pháp khác nhau
Đối với các giải pháp sản xuất, chúng tôi khuyên bạn nên kết hợp các proxy chất lượng với cấu hình fingerprint đúng cách, xử lý lỗi và giám sát. Điều này sẽ đảm bảo hoạt động ổn định của trình thu thập dữ liệu ngay cả trên các trang web bảo mật.
Nếu bạn dự định phân tích các trang web thương mại, thị trường hoặc làm việc với các nền tảng quảng cáo, chúng tôi khuyên bạn nên sử dụng proxy dân cư — chúng đảm bảo tính ẩn danh tối đa và rủi ro bị chặn tối thiểu nhờ vào các địa chỉ IP thực của người dùng gia đình.