Cách giải Captcha trong Maxun với tích hợp CapSolver

Anh Tuan
Data Science Expert
21-Jan-2026

Trong trích xuất dữ liệu web, Maxun đang thu hút sự chú ý như một nền tảng mở mã nguồn, không cần lập trình, giúp các nhóm thu thập dữ liệu từ web dễ dàng hơn. Các quy trình dựa trên robot và SDK của nó cho phép cả lập trình viên và người dùng không chuyên xây dựng và duy trì các pipeline trích xuất dữ liệu mà không cần nỗ lực kỹ thuật lớn.
Tuy nhiên, nhiều trang web thực tế được bảo vệ bởi CAPTCHA, thường trở thành rào cản chính trong quá trình trích xuất dữ liệu. CapSolver hoạt động tốt cùng Maxun bằng cách xử lý các thách thức này ở cấp độ cơ sở hạ tầng. Với CapSolver, các robot Maxun có thể tiếp tục hoạt động trên các trang web có CAPTCHA một cách tin cậy hơn, kết hợp sự dễ sử dụng với khả năng trích xuất thực tế, sẵn sàng cho sản xuất.
Maxun là gì?
Maxun là một nền tảng trích xuất dữ liệu web mở mã nguồn, không cần lập trình, cho phép người dùng huấn luyện robot để trích xuất trang web mà không cần viết mã. Nó có giao diện trực quan để xây dựng robot, SDK mạnh mẽ để kiểm soát robot theo chương trình, và hỗ trợ triển khai trên đám mây và tự lưu trữ.
Tính năng chính của Maxun
- Trình xây dựng robot không cần lập trình: Giao diện trực quan để huấn luyện robot trích xuất dữ liệu mà không cần lập trình
- SDK mạnh mẽ: SDK TypeScript/Node.js để điều khiển robot theo chương trình
- Nhiều chế độ trích xuất: Khả năng trích xuất, trích xuất, duyệt và tìm kiếm
- Chọn phần tử thông minh: Phát hiện tự động các phần tử và tạo các lựa chọn thông minh
- Đám mây & Tự lưu trữ: Triển khai trên Maxun Cloud hoặc cơ sở hạ tầng của bạn
- Hỗ trợ proxy: Quản lý và quay proxy tích hợp
- Chạy theo lịch trình: Tự động hóa việc chạy robot với lịch trình dựa trên cron
Các lớp SDK chính
| Lớp | Mô tả |
|---|---|
| Trích xuất | Xây dựng các quy trình trích xuất dữ liệu có cấu trúc với LLM hoặc các lựa chọn CSS |
| Trích xuất trang web | Chuyển trang web thành Markdown, HTML hoặc hình ảnh chụp màn hình sạch sẽ |
| Duyệt trang web | Tự động phát hiện và trích xuất nhiều trang bằng sitemap và liên kết |
| Tìm kiếm | Thực hiện tìm kiếm web và trích xuất nội dung từ kết quả (DuckDuckGo) |
Điều gì làm cho Maxun khác biệt
Maxun cầu nối khoảng cách giữa sự đơn giản không cần lập trình và sự linh hoạt cho lập trình viên:
- Giao diện trực quan + Mã hóa: Huấn luyện robot trực quan, sau đó điều khiển chúng theo chương trình qua SDK
- Kiến trúc dựa trên robot: Mẫu trích xuất có thể tái sử dụng và chia sẻ
- Tương thích TypeScript: Xây dựng cho các ứng dụng Node.js hiện đại
- Mã nguồn mở: Minh bạch toàn diện và phát triển dựa trên cộng đồng
CapSolver là gì?
CapSolver là một dịch vụ giải CAPTCHA hàng đầu cung cấp các giải pháp dựa trên AI để vượt qua các thách thức CAPTCHA khác nhau. Với sự hỗ trợ cho nhiều loại CAPTCHA và thời gian phản hồi nhanh chóng, CapSolver tích hợp dễ dàng vào các quy trình tự động hóa.
Các loại CAPTCHA được hỗ trợ
CapSolver giúp các quy trình tự động hóa xử lý hầu hết các CAPTCHA và cơ chế xác minh chính thống thường gặp trong trích xuất web và tự động hóa trình duyệt, bao gồm:
- reCAPTCHA v2 (dựa trên hình ảnh & không nhìn thấy)
- reCAPTCHA v3 & v3 Enterprise
- Cloudflare Turnstile
- Cloudflare 5-second Challenge
- AWS WAF CAPTCHA
- Các loại CAPTCHA và cơ chế chống bot phổ biến khác
Tại sao tích hợp CapSolver với Maxun?
Khi xây dựng robot Maxun tương tác với các trang web được bảo vệ—dù là trích xuất dữ liệu, theo dõi giá, hay nghiên cứu thị trường—các thách thức CAPTCHA trở thành rào cản lớn. Dưới đây là lý do tại sao tích hợp quan trọng:
- Trích xuất dữ liệu liên tục: Robot có thể hoàn thành nhiệm vụ mà không cần can thiệp thủ công
- Thao tác có thể mở rộng: Xử lý các thách thức CAPTCHA trên nhiều lần thực thi robot song song
- Quy trình liền mạch: Giải CAPTCHA như một phần của pipeline trích xuất của bạn
- Hiệu quả về chi phí: Chỉ thanh toán cho các CAPTCHA được giải thành công
- Tỷ lệ thành công cao: Độ chính xác hàng đầu trong tất cả các loại CAPTCHA được hỗ trợ
Cài đặt
Yêu cầu
- Node.js 18 hoặc cao hơn
- npm hoặc yarn
- Một khóa API CapSolver

Cài đặt SDK Maxun
bash
# Cài đặt SDK Maxun
npm install maxun-sdk
# Cài đặt các phụ thuộc bổ sung cho tích hợp CapSolver
npm install axios
Cài đặt Docker (Maxun tự lưu trữ)
bash
# Sao chép kho lưu trữ Maxun
git clone https://github.com/getmaxun/maxun.git
cd maxun
# Chạy bằng Docker Compose
docker-compose up -d
Thiết lập môi trường
Tạo một tệp .env với cấu hình của bạn:
env
CAPSOLVER_API_KEY=your_capsolver_api_key
MAXUN_API_KEY=your_maxun_api_key
# Đối với Maxun Cloud (app.maxun.dev)
MAXUN_BASE_URL=https://app.maxun.dev/api/sdk
# Đối với Maxun tự lưu trữ (mặc định)
# MAXUN_BASE_URL=http://localhost:8080/api/sdk
Lưu ý: Cấu hình baseUrl là bắt buộc khi sử dụng Maxun Cloud. Các cài đặt tự lưu trữ mặc định là
http://localhost:8080/api/sdk.
Tạo dịch vụ CapSolver cho Maxun
Dưới đây là một dịch vụ TypeScript có thể tái sử dụng tích hợp CapSolver với Maxun:
Dịch vụ CapSolver cơ bản
typescript
import axios, { AxiosInstance } from 'axios';
interface TaskResult {
gRecaptchaResponse?: string;
token?: string;
cookies?: Array<{ name: string; value: string }>;
userAgent?: string;
}
interface CapSolverConfig {
apiKey: string;
timeout?: number;
maxAttempts?: number;
}
class CapSolverService {
private client: AxiosInstance;
private apiKey: string;
private maxAttempts: number;
constructor(config: CapSolverConfig) {
this.apiKey = config.apiKey;
this.maxAttempts = config.maxAttempts || 60;
this.client = axios.create({
baseURL: 'https://api.capsolver.com',
timeout: config.timeout || 30000,
headers: { 'Content-Type': 'application/json' },
});
}
private async createTask(taskData: Record<string, unknown>): Promise<string> {
const response = await this.client.post('/createTask', {
clientKey: this.apiKey,
task: taskData,
});
if (response.data.errorId !== 0) {
throw new Error(`Lỗi CapSolver: ${response.data.errorDescription}`);
}
return response.data.taskId;
}
private async getTaskResult(taskId: string): Promise<TaskResult> {
for (let attempt = 0; attempt < this.maxAttempts; attempt++) {
await this.delay(2000);
const response = await this.client.post('/getTaskResult', {
clientKey: this.apiKey,
taskId,
});
const { status, solution, errorDescription } = response.data;
if (status === 'ready') {
return solution as TaskResult;
}
if (status === 'failed') {
throw new Error(`Nhiệm vụ thất bại: ${errorDescription}`);
}
}
throw new Error('Hết thời gian chờ giải CAPTCHA');
}
private delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async solveReCaptchaV2(websiteUrl: string, websiteKey: string): Promise<string> {
const taskId = await this.createTask({
type: 'ReCaptchaV2TaskProxyLess',
websiteURL: websiteUrl,
websiteKey,
});
const solution = await this.getTaskResult(taskId);
return solution.gRecaptchaResponse || '';
}
async solveReCaptchaV3(
websiteUrl: string,
websiteKey: string,
pageAction: string = 'submit'
): Promise<string> {
const taskId = await this.createTask({
type: 'ReCaptchaV3TaskProxyLess',
websiteURL: websiteUrl,
websiteKey,
pageAction,
});
const solution = await this.getTaskResult(taskId);
return solution.gRecaptchaResponse || '';
}
async solveTurnstile(
websiteUrl: string,
websiteKey: string,
action?: string,
cdata?: string
): Promise<string> {
const taskData: Record<string, unknown> = {
type: 'AntiTurnstileTaskProxyLess',
websiteURL: websiteUrl,
websiteKey,
};
// Thêm thông tin tùy chọn
if (action || cdata) {
taskData.metadata = {};
if (action) (taskData.metadata as Record<string, string>).action = action;
if (cdata) (taskData.metadata as Record<string, string>).cdata = cdata;
}
const taskId = await this.createTask(taskData);
const solution = await this.getTaskResult(taskId);
return solution.token || '';
}
async checkBalance(): Promise<number> {
const response = await this.client.post('/getBalance', {
clientKey: this.apiKey,
});
return response.data.balance || 0;
}
}
export { CapSolverService, CapSolverConfig, TaskResult };
★ Gợi ý ─────────────────────────────────────
Dịch vụ CapSolver sử dụng mẫu polling (getTaskResult) vì việc giải CAPTCHA là bất đồng bộ—API chấp nhận một nhiệm vụ, xử lý nó trên máy chủ của họ, và trả về kết quả khi sẵn sàng. Khoảng thời gian 2 giây giữa các lần kiểm tra cân bằng giữa tính phản hồi và giới hạn tần suất API.
─────────────────────────────────────────────────
Giải các loại CAPTCHA khác nhau
reCAPTCHA v2 với Maxun
Vì Maxun hoạt động ở cấp độ cao hơn so với tự động hóa trình duyệt, cách tích hợp tập trung vào việc giải CAPTCHA trước hoặc trong khi thực thi robot:
typescript
import { Trích xuất } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';
const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const extractor = new Trích xuất({
apiKey: MAXUN_API_KEY,
baseUrl: MAXUN_BASE_URL,
});
async function trích xuấtVớiReCaptchaV2() {
const targetUrl = 'https://example.com/trang-bảo-mật';
const reCAPTCHA_siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';
console.log('Giải reCAPTCHA v2...');
// Giải CAPTCHA trước tiên
const token = await capSolver.solveReCaptchaV2(targetUrl, reCAPTCHA_siteKey);
console.log('CAPTCHA đã được giải, tạo robot trích xuất...');
// Tạo robot bằng cách chuỗi phương thức
const robot = await extractor
.tạo('Trình trích xuất sản phẩm')
.điều hướng(targetUrl)
.nhập('#g-recaptcha-response', token)
.nhấn('nút[type="submit"]')
.chờ(2000)
.thu-thập-danh-sách({ selector: '.sản-phẩm' });
// Chạy robot
const kết_quả = await robot.chạy({ timeout: 30000 });
console.log('Trích xuất hoàn tất:', kết_quả.dữ_liệu);
return kết_quả.dữ_liệu;
}
trích xuấtVớiReCaptchaV2().catch(console.error);
reCAPTCHA v3 với Maxun
typescript
import { Trích xuất } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';
const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const extractor = new Trích xuất({
apiKey: MAXUN_API_KEY,
baseUrl: MAXUN_BASE_URL,
});
async function trích xuấtVớiReCaptchaV3() {
const targetUrl = 'https://example.com/v3-bảo-mật';
const reCAPTCHA_siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDEF';
console.log('Giải reCAPTCHA v3 với điểm số cao...');
// Giải với hành động trang tùy chỉnh
const token = await capSolver.solveReCaptchaV3(
targetUrl,
reCAPTCHA_siteKey,
'submit' // hành động trang
);
console.log('Token đã được nhận với điểm số cao, tạo robot...');
// Tạo robot trích xuất bằng cách chuỗi phương thức
const robot = await extractor
.tạo('Trình trích xuất bảo vệ v3')
.điều hướng(targetUrl)
.nhập('input[name="g-recaptcha-response"]', token)
.nhấn('#nút-gửi')
.chờ(2000)
.thu-thập-text({ kết_quả: '.kết_quả' });
const kết_quả = await robot.chạy({ timeout: 30000 });
console.log('Dữ liệu trích xuất:', kết_quả.dữ_liệu);
return kết_quả.dữ_liệu;
}
trích xuấtVớiReCaptchaV3().catch(console.error);
Cloudflare Turnstile với Maxun
typescript
import { Trích xuất } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';
const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const scraper = new Trích xuất({
apiKey: MAXUN_API_KEY,
baseUrl: MAXUN_BASE_URL,
});
async function trích xuấtVớiTurnstile() {
const targetUrl = 'https://example.com/turnstile-bảo-mật';
const turnstile_siteKey = '0x4xxxxxxxxxxxxxxxxxxxxxxxxxxxxGHI';
console.log('Giải Cloudflare Turnstile...');
// Giải với thông tin tùy chọn (action và cdata)
const token = await capSolver.solveTurnstile(
targetUrl,
turnstile_siteKey,
'đăng nhập', // hành động tùy chọn
'0000-1111-2222-3333-thông-tin-cdata' // thông tin cdata tùy chọn
);
console.log('Turnstile đã được giải, tạo robot trích xuất...');
// Tạo robot trích xuất - đối với Turnstile, chúng ta thường cần
// gửi token qua yêu cầu POST trước, sau đó trích xuất
const robot = await scraper.tạo('trình-trích-xuất-turnstile', targetUrl, {
định_dạng: ['markdown', 'html'],
});
const kết_quả = await robot.chạy({ timeout: 30000 });
console.log('Trích xuất hoàn tất');
console.log('Markdown:', kết_quả.dữ_liệu.markdown?.substring(0, 500));
return kết_quả.dữ_liệu;
}
trích xuấtVớiTurnstile().catch(console.error);
Tích hợp với quy trình Maxun
Sử dụng với lớp Trích xuất
Lớp Trích xuất được sử dụng để trích xuất dữ liệu có cấu trúc từ các phần tử trang cụ thể. Nó hỗ trợ trích xuất được hỗ trợ bởi LLM (dùng lời nhắc ngôn ngữ tự nhiên) và trích xuất không LLM (dùng các lựa chọn CSS):
typescript
import { Trích xuất } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const extractor = new Trích xuất({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});
interface DữLiệuSảnPhẩm {
tên: string;
giá: string;
đánh_giá: string;
}
async function trích xuấtSảnPhẩmVớiCaptcha(): Promise<DữLiệuSảnPhẩm[]> {
const targetUrl = 'https://example.com/products';
const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';
// Giải CAPTCHA trước
const captchaToken = await capSolver.solveReCaptchaV2(targetUrl, siteKey);
console.log('CAPTCHA đã được giải, tạo robot trích xuất...');
// Tạo robot trích xuất bằng cách kế thừa phương thức
const robot = await extractor
.create('Trình trích xuất sản phẩm')
.navigate(targetUrl)
.type('#g-recaptcha-response', captchaToken)
.click('button[type="submit"]')
.wait(3000)
.captureList({
selector: '.product-card',
pagination: { type: 'clickNext', selector: '.next-page' },
maxItems: 50,
});
// Chạy trích xuất
const result = await robot.run({ timeout: 60000 });
return result.data.listData as ProductData[];
}
extractProductsWithCaptcha()
.then((products) => {
products.forEach((product) => {
console.log(`${product.name}: ${product.price}`);
});
})
.catch(console.error);
★ Insight ─────────────────────────────────────
Phương thức captureList trong lớp Extract của Maxun tự động phát hiện các trường trong các mục danh sách và xử lý phân trang. Khi bạn chỉ định loại phân trang (scrollDown, clickNext, hoặc clickLoadMore), robot sẽ tiếp tục trích xuất cho đến khi đạt giới hạn của bạn hoặc hết trang.
─────────────────────────────────────────────────
Sử dụng với lớp Scrape
Lớp Scrape chuyển trang web thành HTML sạch, Markdown phù hợp với LLM, hoặc hình ảnh chụp màn hình:
typescript
import { Scrape } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
import axios from 'axios';
const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const scraper = new Scrape({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});
interface ScrapeResult {
url: string;
markdown?: string;
html?: string;
captchaSolved: boolean;
}
async function scrapeWithCaptchaHandling(): Promise<ScrapeResult[]> {
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3',
];
const results: ScrapeResult[] = [];
for (const url of urls) {
try {
// Đối với các trang bị CAPTCHA, giải trước và thiết lập phiên
const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC'; // Lấy động nếu cần
console.log(`Giải CAPTCHA cho ${url}...`);
const captchaToken = await capSolver.solveReCaptchaV2(url, siteKey);
// Gửi CAPTCHA để nhận cookie phiên
const verifyResponse = await axios.post(`${url}/verify`, {
'g-recaptcha-response': captchaToken,
});
// Tạo robot ghi chú cho trang đã xác thực
const robot = await scraper.create(`scraper-${Date.now()}`, url, {
formats: ['markdown', 'html'],
});
const result = await robot.run({ timeout: 30000 });
results.push({
url,
markdown: result.data.markdown,
html: result.data.html,
captchaSolved: true,
});
// Dọn dẹp - xóa robot sau khi sử dụng
await robot.delete();
} catch (error) {
console.error(`Không thể ghi chú ${url}:`, error);
results.push({ url, captchaSolved: false });
}
}
return results;
}
scrapeWithCaptchaHandling().then(console.log).catch(console.error);
Sử dụng với lớp Crawl
Lớp Crawl tự động phát hiện và ghi chú nhiều trang bằng cách sử dụng sitemap và theo dõi liên kết:
typescript
import { Crawl } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
import axios from 'axios';
const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const crawler = new Crawl({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});
interface PageResult {
url: string;
title: string;
text: string;
wordCount: number;
}
async function crawlWithCaptchaProtection(): Promise<PageResult[]> {
const startUrl = 'https://example.com';
const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';
// Giải CAPTCHA cho miền trước
console.log('Giải CAPTCHA để truy cập miền...');
const captchaToken = await capSolver.solveReCaptchaV2(startUrl, siteKey);
// Gửi CAPTCHA để thiết lập phiên (tùy theo miền)
await axios.post(`${startUrl}/verify`, {
'g-recaptcha-response': captchaToken,
});
// Tạo robot ghi chú với cấu hình theo miền
const robot = await crawler.create('site-crawler', startUrl, {
mode: 'domain', // Phạm vi ghi chú: 'domain', 'subdomain', hoặc 'path'
limit: 50, // Số trang tối đa để ghi chú
maxDepth: 3, // Sâu tối đa để theo dõi liên kết
useSitemap: true, // Phân tích sitemap.xml để lấy URL
followLinks: true, // Trích xuất và theo dõi liên kết trang
includePaths: ['/blog/', '/docs/'], // Mẫu regex để bao gồm
excludePaths: ['/admin/', '/login/'], // Mẫu regex để loại trừ
respectRobots: true, // Tôn trọng robots.txt
});
// Chạy ghi chú
const result = await robot.run({ timeout: 120000 });
// Mỗi trang trong kết quả chứa: metadata, html, text, wordCount, links
return result.data.crawlData.map((page: any) => ({
url: page.metadata.url,
title: page.metadata.title,
text: page.text,
wordCount: page.wordCount,
}));
}
crawlWithCaptchaProtection()
.then((pages) => {
console.log(`Đã ghi chú ${pages.length} trang`);
pages.forEach((page) => {
console.log(`- ${page.title}: ${page.url} (${page.wordCount} từ)`);
});
})
.catch(console.error);
Mẫu Xác thực Trước
Đối với các trang yêu cầu CAPTCHA trước khi truy cập nội dung, sử dụng quy trình xác thực trước:
typescript
import axios from 'axios';
import { Extract } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const extractor = new Extract({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});
interface SessionCookies {
name: string;
value: string;
domain: string;
}
async function preAuthenticateWithCaptcha(
loginUrl: string,
siteKey: string
): Promise<SessionCookies[]> {
// Bước 1: Giải CAPTCHA
const captchaToken = await capSolver.solveReCaptchaV2(loginUrl, siteKey);
// Bước 2: Gửi token CAPTCHA để nhận cookie phiên
const response = await axios.post(
loginUrl,
{
'g-recaptcha-response': captchaToken,
},
{
withCredentials: true,
maxRedirects: 0,
validateStatus: (status) => status < 400,
}
);
// Bước 3: Trích xuất cookie từ phản hồi
const setCookies = response.headers['set-cookie'] || [];
const cookies: SessionCookies[] = setCookies.map((cookie: string) => {
const [nameValue] = cookie.split(';');
const [name, value] = nameValue.split('=');
return {
name: name.trim(),
value: value.trim(),
domain: new URL(loginUrl).hostname,
};
});
return cookies;
}
async function extractWithPreAuth() {
const loginUrl = 'https://example.com/verify';
const targetUrl = 'https://example.com/protected-data';
const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';
// Xác thực trước để nhận cookie phiên
const sessionCookies = await preAuthenticateWithCaptcha(loginUrl, siteKey);
console.log('Phiên đã thiết lập, tạo robot trích xuất...');
// Tạo robot trích xuất bằng cách kế thừa phương thức
// Lưu ý: Sử dụng setCookies() để truyền cookie phiên đã xác thực
const robot = await extractor
.create('Trình trích xuất đã xác thực')
.setCookies(sessionCookies)
.navigate(targetUrl)
.wait(2000)
.captureText({ content: '.protected-content' });
// Chạy trích xuất
const result = await robot.run({ timeout: 30000 });
return result.data;
}
extractWithPreAuth().then(console.log).catch(console.error);
★ Insight ─────────────────────────────────────
Mẫu xác thực trước tách biệt việc giải CAPTCHA khỏi việc trích xuất dữ liệu. Điều này đặc biệt hữu ích với Maxun vì nó hoạt động ở mức trừu tượng cao hơn—thay vì chèn token vào DOM, bạn thiết lập phiên đã xác thực trước, sau đó để robot của Maxun làm việc trong phiên đó.
─────────────────────────────────────────────────
Chạy Nhiều Robot Song Song Với Xử Lý CAPTCHA
Xử lý CAPTCHA trên nhiều phiên robot song song:
typescript
import { Scrape } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const scraper = new Scrape({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});
interface ExtractionJob {
url: string;
siteKey?: string;
}
interface ExtractionResult {
url: string;
data: { markdown?: string; html?: string };
captchaSolved: boolean;
duration: number;
}
async function processJob(job: ExtractionJob): Promise<ExtractionResult> {
const startTime = Date.now();
let captchaSolved = false;
// Giải CAPTCHA nếu có site key
if (job.siteKey) {
console.log(`Giải CAPTCHA cho ${job.url}...`);
const token = await capSolver.solveReCaptchaV2(job.url, job.siteKey);
captchaSolved = true;
// Token sẽ được gửi để thiết lập phiên trước khi ghi chú
}
// Tạo và chạy robot ghi chú
const robot = await scraper.create(`scraper-${Date.now()}`, job.url, {
formats: ['markdown', 'html'],
});
const result = await robot.run({ timeout: 30000 });
// Dọn dẹp robot sau khi sử dụng
await robot.delete();
return {
url: job.url,
data: {
markdown: result.data.markdown,
html: result.data.html,
},
captchaSolved,
duration: Date.now() - startTime,
};
}
async function runParallelExtractions(
jobs: ExtractionJob[],
concurrency: number = 5
): Promise<ExtractionResult[]> {
const results: ExtractionResult[] = [];
const chunks: ExtractionJob[][] = [];
// Chia công việc thành các khối để kiểm soát độ đồng thời
for (let i = 0; i < jobs.length; i += concurrency) {
chunks.push(jobs.slice(i, i + concurrency));
}
for (const chunk of chunks) {
const chunkResults = await Promise.all(chunk.map(processJob));
results.push(...chunkResults);
}
return results;
}
// Ví dụ sử dụng
const jobs: ExtractionJob[] = [
{ url: 'https://site1.com/data', siteKey: '6Lc...' },
{ url: 'https://site2.com/data' },
{ url: 'https://site3.com/data', siteKey: '6Lc...' },
// ... nhiều công việc hơn
];
runParallelExtractions(jobs, 5)
.then((results) => {
const solved = results.filter((r) => r.captchaSolved).length;
console.log(`Hoàn thành ${results.length} trích xuất, giải được ${solved} CAPTCHA`);
results.forEach((r) => {
console.log(`${r.url}: ${r.duration}ms`);
});
})
.catch(console.error);
Các Nguyên Tắc Tốt
1. Xử Lý Lỗi Với Thử Lại
typescript
async function solveWithRetry<T>(
solverFn: () => Promise<T>,
maxRetries: number = 3
): Promise<T> {
let lastError: Error | undefined;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await solverFn();
} catch (error) {
lastError = error as Error;
console.warn(`Lần thử ${attempt + 1} thất bại: ${lastError.message}`);
// Tái thử theo cấp số nhân
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
}
}
throw new Error(`Đã vượt quá số lần thử lại: ${lastError?.message}`);
}
// Sử dụng
const token = await solveWithRetry(() =>
capSolver.solveReCaptchaV2(url, siteKey)
);
2. Quản Lý Số Dư
typescript
async function ensureSufficientBalance(minBalance: number = 1.0): Promise<void> {
const balance = await capSolver.checkBalance();
if (balance < minBalance) {
throw new Error(
`Số dư CapSolver không đủ: $${balance.toFixed(2)}. Vui lòng nạp tiền.`
);
}
console.log(`Số dư CapSolver: $${balance.toFixed(2)}`);
}
// Kiểm tra số dư trước khi bắt đầu công việc trích xuất
await ensureSufficientBalance(5.0);
3. Lưu Trữ Token
typescript
interface CachedToken {
token: string;
timestamp: number;
}
class TokenCache {
private cache = new Map<string, CachedToken>();
private ttlMs: number;
constructor(ttlSeconds: number = 90) {
this.ttlMs = ttlSeconds * 1000;
}
private getKey(domain: string, siteKey: string): string {
return `${domain}:${siteKey}`;
}
get(domain: string, siteKey: string): string | null {
const key = this.getKey(domain, siteKey);
const cached = this.cache.get(key);
if (!cached) return null;
if (Date.now() - cached.timestamp > this.ttlMs) {
this.cache.delete(key);
return null;
}
return cached.token;
}
set(domain: string, siteKey: string, token: string): void {
const key = this.getKey(domain, siteKey);
this.cache.set(key, { token, timestamp: Date.now() });
}
}
const tokenCache = new TokenCache(90);
async function getCachedOrSolve(
url: string,
siteKey: string
): Promise<string> {
const domain = new URL(url).hostname;
const cached = tokenCache.get(domain, siteKey);
if (cached) {
console.log('Sử dụng token đã lưu');
return cached;
}
const token = await capSolver.solveReCaptchaV2(url, siteKey);
tokenCache.set(domain, siteKey, token);
return token;
}
Các Tùy Chọn Cấu Hình
Maxun hỗ trợ cấu hình thông qua biến môi trường và tùy chọn SDK:
| Cài đặt | Mô tả | Mặc định |
|---|---|---|
MAXUN_API_KEY |
Mã API Maxun của bạn | - |
MAXUN_BASE_URL |
URL cơ sở API Maxun | http://localhost:8080/api/sdk (tự host) hoặc https://app.maxun.dev/api/sdk (đám mây) |
CAPSOLVER_API_KEY |
Mã API CapSolver của bạn | - |
CAPSOLVER_TIMEOUT |
Thời gian chờ yêu cầu tính bằng ms | 30000 |
CAPSOLVER_MAX_ATTEMPTS |
Số lần thử tối đa | 60 |
Cấu Hình SDK
typescript
import { Extract, Scrape, Crawl, Search } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
// Đối với Maxun Cloud (app.maxun.dev)
const MAXUN_BASE_URL = 'https://app.maxun.dev/api/sdk';
// Đối với Maxun tự host (mặc định)
// const MAXUN_BASE_URL = 'http://localhost:8080/api/sdk';
// Cấu hình các module SDK Maxun
const extractor = new Extract({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: MAXUN_BASE_URL,
});
const scraper = new Scrape({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: MAXUN_BASE_URL,
});
const crawler = new Crawl({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: MAXUN_BASE_URL,
});
const searcher = new Search({
apiKey: process.env.MAXUN_API_KEY!,
baseUrl: MAXUN_BASE_URL,
});
// Cấu hình CapSolver
const capSolver = new CapSolverService({
Tuyên bố Tuân thủ: Thông tin được cung cấp trên blog này chỉ mang tính chất tham khảo. CapSolver cam kết tuân thủ tất cả các luật và quy định hiện hành. Việc sử dụng mạng lưới CapSolver cho các hoạt động bất hợp pháp, gian lận hoặc lạm dụng là hoàn toàn bị cấm và sẽ bị điều tra. Các giải pháp giải captcha của chúng tôi nâng cao trải nghiệm người dùng trong khi đảm bảo tuân thủ 100% trong việc giúp giải quyết các khó khăn về captcha trong quá trình thu thập dữ liệu công khai. Chúng tôi khuyến khích việc sử dụng dịch vụ của chúng tôi một cách có trách nhiệm. Để biết thêm thông tin, vui lòng truy cập Điều khoản Dịch vụ và Chính sách Quyền riêng tư.
Thêm

Cách giải Captcha trong Maxun với tích hợp CapSolver
Một hướng dẫn thực tế về việc tích hợp CapSolver với Maxun cho quét web thực tế. Học cách xử lý reCAPTCHA, Cloudflare Turnstile và các trang web được bảo vệ bằng CAPTCHA bằng cách sử dụng quy trình xác thực trước và luồng công việc robot.

Anh Tuan
21-Jan-2026

Cách giải Captcha trong Browser4 với tích hợp CapSolver
Tự động hóa Browser4 tỷ lệ xử lý cao kết hợp với CapSolver để xử lý các thách thức CAPTCHA trong việc trích xuất dữ liệu web quy mô lớn.

Anh Tuan
21-Jan-2026

Bot rút trích là gì và cách xây dựng một cái
Học về bot quét và cách xây dựng một bot để trích xuất dữ liệu tự động. Khám phá các công cụ hàng đầu, kỹ thuật vượt qua bảo mật và thực hành trích xuất dữ liệu có đạo đức.

Anh Tuan
15-Jan-2026

Scrapy so với Selenium: Cái nào tốt nhất cho Dự án Ghi dữ liệu từ Web của bạn?
Khám phá các điểm mạnh và sự khác biệt giữa Scrapy và Selenium trong việc quét dữ liệu trên web. Học cách chọn công cụ phù hợp nhất với dự án của bạn và cách xử lý các thách thức như CAPTCHAs.

Rajinder Singh
14-Jan-2026

Cách sử dụng Selenium Driverless để quét web hiệu quả
Học cách sử dụng Selenium Driverless để quét web hiệu quả. Hướng dẫn này cung cấp các bước từng bước để cài đặt môi trường của bạn, viết script Selenium Driverless đầu tiên của bạn và xử lý nội dung động. Tối ưu hóa các nhiệm vụ quét web bằng cách tránh sự phức tạp trong quản lý WebDriver truyền thống, giúp quy trình trích xuất dữ liệu của bạn trở nên đơn giản hơn, nhanh hơn và dễ di chuyển hơn.

Sora Fujimoto
14-Jan-2026

Giải quyết lỗi 403 Truy cập bị từ chối khi quét trang web bằng Python
Học cách vượt qua các lỗi 403 Forbidden khi quét trang web bằng Python. Hướng dẫn này bao gồm quay vòng IP, giả mạo user-agent, kiểm soát tần suất yêu cầu, xử lý xác thực và sử dụng trình duyệt không đầu để vượt qua các hạn chế truy cập và tiếp tục quét web thành công.

Sora Fujimoto
13-Jan-2026

