
Aloísio Vítor
Image Processing Expert

AWS WAF (Tường lửa ứng dụng web) là hệ thống bảo vệ bot cấp doanh nghiệp của Amazon được sử dụng bởi một số trang web lớn nhất trên Internet. Không giống như các CAPTCHA truyền thống hiển thị câu đố hình ảnh hoặc hộp kiểm, AWS WAF sử dụng các thử thách vô hình và xác minh dựa trên mã thông báo — điều này khiến các công cụ tự động hóa đặc biệt khó xử lý.
Điều gì sẽ xảy ra nếu bạn có thể tự động giải quyết các thử thách AWS WAF trong quy trình làm việc n8n của mình, cho dù bạn đang xây dựng một API giải quyết có thể tái sử dụng, thu thập dữ liệu từ một trang web được bảo vệ bằng CAPTCHA hay tự động hóa một biểu mẫu đăng nhập — tất cả mà không cần viết một dòng mã truyền thống nào?
Trong hướng dẫn này, bạn sẽ học cách kết hợp n8n (một công cụ tự động hóa quy trình làm việc trực quan) với CapSolver (một dịch vụ giải CAPTCHA được hỗ trợ bởi AI) để giải quyết các thử thách AWS WAF theo yêu cầu — dưới dạng một điểm cuối API độc lập hoặc là một bước trong bất kỳ quy trình làm việc tự động hóa lớn hơn nào.
Bạn sẽ xây dựng gì:
API giải quyết — một điểm cuối có thể tái sử dụng mà các công cụ khác của bạn có thể gọi:
Quy trình làm việc sử dụng trực tiếp — CapSolver được nhúng như một bước trong các tự động hóa lớn hơn:
AWS WAF (Tường lửa ứng dụng web) là dịch vụ giảm thiểu bot và bảo mật web của Amazon Web Services. Nó bảo vệ các trang web khỏi các cuộc tấn công web phổ biến, lưu lượng bot và lạm dụng tự động. Nhiều trang web có lưu lượng truy cập cao — đặc biệt là các nền tảng thương mại điện tử, dịch vụ tài chính và ứng dụng doanh nghiệp — sử dụng AWS WAF để hạn chế quyền truy cập đằng sau các thử thách CAPTCHA vô hình.
AWS WAF khác với reCAPTCHA và Turnstile như thế nào:
websiteURL để bắt đầu giải quyết.aws-waf-token phải được gửi cùng với các yêu cầu tiếp theo thông qua tiêu đề HTTP Cookie.awsKey, awsIv, awsContext, awsChallengeJS và các tham số khác tùy thuộc vào cấu hình của trang web. Đây là tùy chọn và chỉ cần thiết cho các triển khai cụ thể.
Không giống như CloudFront. AWS WAF là lớp tường lửa nằm phía trước các ứng dụng web. CloudFront là CDN của Amazon. Một trang web có thể sử dụng CloudFront mà không cần AWS WAF, hoặc AWS WAF mà không cần CloudFront — chúng là các dịch vụ riêng biệt, mặc dù thường được sử dụng cùng nhau.
Trước khi bắt đầu, hãy đảm bảo bạn có những điều sau:
Quan trọng: Đảm bảo bạn có đủ số dư trong tài khoản CapSolver của mình. Các tác vụ giải quyết AWS WAF tiêu thụ tín dụng dựa trên mức sử dụng.
CapSolver có sẵn dưới dạng tích hợp chính thức trong n8n — không cần cài đặt nút cộng đồng. Bạn có thể tìm thấy nó trực tiếp trong bảng nút khi xây dựng quy trình làm việc của mình.
Vì đây là một tích hợp chính thức, bạn cần tạo thông tin xác thực trong n8n để nút CapSolver có thể xác thực với tài khoản của bạn.
Đi tới phiên bản n8n của bạn và điều hướng đến Settings -> Credentials. Bạn sẽ thấy tất cả thông tin xác thực đã định cấu hình của mình ở đây.

All (mặc định)n8n sẽ tự động kiểm tra kết nối. Bạn sẽ thấy một biểu ngữ màu xanh lá cây "Connection tested successfully" xác nhận rằng khóa API của bạn hợp lệ.

Quan trọng: Mỗi nút CapSolver trong quy trình làm việc của bạn sẽ tham chiếu thông tin xác thực này. Bạn chỉ cần tạo nó một lần — tất cả các quy trình làm việc giải quyết của bạn sẽ chia sẻ cùng một thông tin xác thực.
Bây giờ bạn đã sẵn sàng xây dựng quy trình làm việc giải quyết AWS WAF của mình!
Trước khi bạn có thể giải quyết thử thách AWS WAF, bạn cần xác nhận rằng trang web mục tiêu đang sử dụng AWS WAF và thu thập bất kỳ tham số tùy chọn nào. Cách dễ nhất là sử dụng Tiện ích mở rộng trình duyệt CapSolver kết hợp với kiểm tra thủ công.
Điều hướng đến trang web mục tiêu của bạn và mở DevTools (F12). Tìm kiếm các dấu hiệu rõ ràng sau:
aws-waf-token trong tab Ứng dụngcaptcha.awswaf.com hoặc các URL chứa challenge.jsx-amzn-waf-*Hầu hết các giải pháp AWS WAF chỉ yêu cầu websiteURL. Tuy nhiên, một số trang web hiển thị các tham số bổ sung có thể cải thiện độ chính xác của giải pháp:
| Tham số | Nơi tìm thấy | Mô tả |
|---|---|---|
awsKey |
Mã nguồn trang / biến JS | Giá trị khóa được trả về bởi trang CAPTCHA |
awsIv |
Mã nguồn trang / biến JS | Giá trị iv được trả về bởi trang CAPTCHA |
awsContext |
Mã nguồn trang / biến JS | Giá trị ngữ cảnh được trả về bởi trang CAPTCHA |
awsChallengeJS |
Tab Mạng | URL challenge.js (ví dụ: https://captcha.awswaf.com/.../challenge.js) |
awsApiJs |
Tab Mạng | URL jsapi.js |
awsProblemUrl |
Tab Mạng | URL điểm cuối vấn đề |
awsApiKey |
Tab Mạng | Giá trị api_key của điểm cuối vấn đề |
awsExistingToken |
Cookies | Một aws-waf-token trước đó nếu làm mới |
Mẹo: Đối với hầu hết các trang web, bạn chỉ cần
websiteURL. Bắt đầu chỉ với tham số đó và chỉ thêm các tham số tùy chọn nếu mã thông báo không được chấp nhận.
Để biết hướng dẫn chi tiết về cách xác định các tham số CAPTCHA, hãy xem tài liệu chính thức của CapSolver.
Quy trình làm việc này tạo một điểm cuối API POST chấp nhận các tham số AWS WAF và trả về một mã thông báo cookie đã giải quyết.

Quy trình làm việc bao gồm bốn nút:
$json.error không trống){"error": "..."} khi thất bại| Cài đặt | Giá trị |
|---|---|
| Phương thức HTTP | POST |
| Đường dẫn | solver-aws-waf |
| Phản hồi | Response Node |
Điều này tạo một điểm cuối tại: https://your-n8n-instance.com/webhook/solver-aws-waf
| Tham số | Giá trị | Mô tả |
|---|---|---|
| Thao tác | AWS WAF |
Phải được đặt thành AWS WAF |
| Loại | AntiAwsWafTaskProxyLess |
Không cần proxy (mặc định). Sử dụng AntiAwsWafTask với proxy cho các trang web nghiêm ngặt hơn |
| URL trang web | {{ $json.body.websiteURL }} |
URL của trang có thử thách AWS WAF |
| awsKey | (Tùy chọn) | Giá trị khóa được trả về bởi trang CAPTCHA |
| awsIv | (Tùy chọn) | Giá trị iv được trả về bởi trang CAPTCHA |
| awsContext | (Tùy chọn) | Giá trị ngữ cảnh được trả về bởi trang CAPTCHA |
| awsChallengeJS | (Tùy chọn) | Liên kết challenge.js |
| awsApiJs | (Tùy chọn) | Liên kết jsapi.js |
Điểm khác biệt chính với Turnstile/reCAPTCHA: AWS WAF không yêu cầu
websiteKey. ChỉwebsiteURLlà bắt buộc. Cũng chọn thông tin xác thực CapSolver của bạn trong nút này.
| Cài đặt | Giá trị |
|---|---|
| Điều kiện | ={{ $json.error }} không trống |
| Nhánh True | Định tuyến đến nút Webhook phản hồi Lỗi |
| Nhánh False | Định tuyến đến nút Webhook phản hồi Thành công |
Điều này làm cho đường dẫn lỗi rõ ràng trên canvas. Nút CapSolver tiếp tục khi có lỗi (onError: continueRegularOutput), vì vậy các lỗi sẽ đến đây dưới dạng {"error": "..."} thay vì làm hỏng quy trình làm việc.
Nhánh thành công (đầu ra False của Lỗi CapSolver?):
| Cài đặt | Giá trị |
|---|---|
| Phản hồi bằng | JSON |
| Nội dung phản hồi | ={{ JSON.stringify($json.data) }} |
Nhánh lỗi (đầu ra True của Lỗi CapSolver?):
| Cài đặt | Giá trị |
|---|---|
| Phản hồi bằng | JSON |
| Nội dung phản hồi | ={{ JSON.stringify({ error: $json.error }) }} |
Các thông báo lỗi tuân theo một trong hai định dạng tùy thuộc vào nơi xảy ra lỗi:
| Điểm lỗi | Định dạng |
|---|---|
| Tạo tác vụ bị từ chối (khóa sai, không có số dư, dữ liệu không hợp lệ, v.v.) | {"error": "Failed to create task: Request failed with status code 400"} |
| Tác vụ đã tạo nhưng CAPTCHA không thể giải quyết | {"error": "Solve failed: <reason>"} |
| Giải quyết hết thời gian chờ sau 120 giây | {"error": "Get task result timeout: unable to solve within 120000 seconds"} |
Lưu ý: Các lỗi tạo tác vụ (khóa API sai, số dư bằng 0, dữ liệu tác vụ không hợp lệ) đều hiển thị dưới dạng cùng một thông báo HTTP 400 — nút n8n bắt ngoại lệ HTTP trước khi đọc nội dung lỗi của CapSolver.
Ví dụ lỗi phổ biến:
{"error": "Failed to create task: Request failed with status code 400"}
{"error": "Solve failed: Invalid parameters"}
{"error": "Get task result timeout: unable to solve within 120000 seconds"}
Gửi yêu cầu POST đến điểm cuối webhook của bạn:
curl -X POST https://your-n8n-instance.com/webhook/solver-aws-waf \
-H "Content-Type: application/json" \
-d '{
"websiteURL": "https://example.com/login"
}'
Phản hồi dự kiến:
{
"taskId": "abc123...",
"solution": {
"cookie": "aws-waf-token=AQAAAA..."
},
"status": "ready"
}
Sao chép JSON bên dưới và nhập vào n8n thông qua Menu -> Import from JSON:
{
"name": "AWS WAF Solver API",
"nodes": [
{
"parameters": {
"content": "## API giải quyết AWS WAF\n\n**Dành cho:** Các nhóm cần giải quyết các thử thách AWS WAF trong các công cụ khác.\n\n**Chức năng:** Chấp nhận các tham số AWS WAF, gửi thử thách đến CapSolver và trả về một cookie `aws-waf-token` đã giải quyết.\n\n**Cách hoạt động:**\n1. Webhook nhận các yêu cầu POST với `websiteURL` và các tham số tùy chọn.\n2. CapSolver giải quyết thử thách AWS WAF.\n3. Khi thành công, Webhook trả về phản hồi JSON chứa cookie `aws-waf-token`.\n4. Khi thất bại, Webhook trả về thông báo lỗi.\n\n**Thiết lập:**\n1. Thêm khóa API CapSolver của bạn trong **Settings → Credentials**.\n2. Kích hoạt quy trình làm việc.\n3. Ghi lại URL Webhook.\n\n**Quan trọng:**\n- AWS WAF không yêu cầu `websiteKey`. Chỉ cần `websiteURL`.\n- Giải pháp là một cookie `aws-waf-token` phải được gửi dưới dạng tiêu đề HTTP `Cookie`.",
"height": 480,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-728,
-400
],
"id": "sticky-blog-main-1773678228095-1",
"name": "Sticky Note"
},
{
"parameters": {
"httpMethod": "POST",
"path": "solver-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
0
],
"id": "aw111111-1111-1111-1111-aw1111111101",
"name": "Webhook Trigger",
"webhookId": "aw111111-aaaa-bbbb-cccc-aw1111111101",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "={{ $json.body.websiteURL }}",
"awsKey": "={{ $json.body.awsKey }}",
"awsIv": "={{ $json.body.awsIv }}",
"awsContext": "={{ $json.body.awsContext }}",
"awsChallengeJS": "={{ $json.body.awsChallengeJS }}",
"awsApiJs": "={{ $json.body.awsApiJs }}",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw111111-1111-1111-1111-aw1111111102",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "aws-if-001",
"leftValue": "={{ $json.error }}",
"operator": {
"type": "string",
"operation": "isEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
208,
0
],
"id": "aw111111-1111-1111-1111-aw1111111103",
"name": "CapSolver Error?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json.data) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
-80
],
"id": "aw111111-1111-1111-1111-aw1111111104",
"name": "Respond to Webhook (Success)"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ error: $json.error }) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
128
],
"id": "aw111111-1111-1111-1111-aw1111111105",
"name": "Respond to Webhook (Error)"
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "CapSolver Error?",
"type": "main",
"index": 0
}
]
]
},
"CapSolver Error?": {
"main": [
[
{
"node": "Respond to Webhook (Success)",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond to Webhook (Error)",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
API giải quyết và ví dụ gửi ở trên cho thấy mô hình cốt lõi: giải quyết thử thách AWS WAF, gửi cookie, xử lý kết quả. Các quy trình làm việc sau đây mở rộng mô hình này thành các trường hợp sử dụng sẵn sàng sản xuất — mỗi trường hợp có hai trình kích hoạt (lịch trình + webhook), theo dõi trạng thái liên tục và đầu ra có cấu trúc.
| Quy trình làm việc | Mục đích |
|---|---|
Thu thập AWS WAF — Chi tiết giá & sản phẩm — CapSolver + Lịch trình + Webhook |
Thu thập giá và tên sản phẩm cứ sau 6 giờ, so sánh với các giá trị trước đó được lưu trữ trong staticData, cảnh báo về các thay đổi |
Đăng nhập tài khoản AWS WAF — CapSolver + Lịch trình + Webhook |
Đăng nhập vào tài khoản của riêng bạn trên một trang web được bảo vệ bằng AWS WAF bằng cách giải quyết trước, sau đó gửi thông tin đăng nhập bằng cookie |
Quy trình làm việc này thu thập một trang sản phẩm cứ sau 6 giờ (lịch trình) hoặc theo yêu cầu (webhook), trích xuất giá bằng nút HTML và so sánh nó với giá trị đã lưu trữ trước đó.
Đường dẫn lịch trình:
Cứ sau 6 giờ -> Giải quyết AWS WAF -> Lấy trang sản phẩm -> Trích xuất dữ liệu
-> So sánh dữ liệu -> Dữ liệu đã thay đổi? -> Xây dựng cảnh báo / Không thay đổi
Các hành vi chính:
Cookie (đây là cách đúng để gửi mã thông báo AWS WAF — không phải dưới dạng trường biểu mẫu).product-price, h1)$workflow.staticData.lastPrice duy trì giá trước đó giữa các lần thực thideal) và tăng (mức độ nghiêm trọng: info){
"name": "AWS WAF Scraping — Price & Product Details — CapSolver + Schedule + Webhook",
"nodes": [
{
"parameters": {
"content": "## Thu thập AWS WAF — Giám sát giá & sản phẩm\n\n**Dành cho:** Các nhóm giám sát giá hoặc dữ liệu sản phẩm trên các trang web được bảo vệ bằng AWS WAF.\n\n**Chức năng:** Giải quyết AWS WAF, tìm nạp trang sản phẩm, trích xuất giá và tên thông qua bộ chọn CSS, so sánh với các giá trị đã lưu trữ và cảnh báo về các thay đổi.\n\n**Cách hoạt động:**\n1. Lịch trình (mỗi 6h) hoặc Webhook kích hoạt luồng\n2. CapSolver giải quyết thử thách AWS WAF\n3. Yêu cầu HTTP tìm nạp trang sản phẩm với mã thông báo đã giải quyết\n4. Nút HTML trích xuất giá và tên sản phẩm\n5. Nút mã so sánh giá hiện tại với giá đã lưu trữ → cảnh báo về các thay đổi\n\n**Thiết lập:**\n1. Thêm khóa API CapSolver của bạn trong **Settings → Credentials**\n2. Thay thế URL giữ chỗ và khóa trang web\n3. Cập nhật bộ chọn CSS trong Trích xuất dữ liệu để khớp với trang mục tiêu của bạn\n4. Kết nối đầu ra của Xây dựng cảnh báo với kênh thông báo của bạn",
"height": 560,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-920,
-380
],
"id": "sticky-blog-main-1773678228094-1",
"name": "Sticky Note"
},
{
"parameters": {
"content": "### Đường dẫn lịch trình\nChạy tự động cứ sau 6 giờ.\nKết quả được lưu trữ trong dữ liệu tĩnh của quy trình làm việc để so sánh giữa các lần thực thi.",
"height": 480,
"width": 1900,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-440,
-280
],
"id": "sticky-blog-section-1773678228094-2",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "### Đường dẫn Webhook\nTrình kích hoạt theo yêu cầu — cùng logic, trả về kết quả dưới dạng phản hồi JSON.",
"height": 480,
"width": 1900,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-440,
140
],
"id": "sticky-blog-section-1773678228094-3",
"name": "Sticky Note2"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-400,
0
],
"id": "aw333333-3333-3333-3333-aw3333333301",
"name": "Every 6 Hours"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "https://YOUR-TARGET-SITE.com/product-page",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw333333-3333-3333-3333-aw3333333302",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"url": "https://YOUR-TARGET-SITE.com/product-page",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Cookie",
"value": "={{ $json.data.solution.cookie }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
0
],
"id": "aw333333-3333-3333-3333-aw3333333303",
"name": "Fetch Product Page"
},
{
"parameters": {
"operation": "extractHtmlContent",
"sourceData": "json",
"dataPropertyName": "data",
"extractionValues": {
"values": [
{
"key": "price",
"cssSelector": ".product-price, [data-price], .price",
"returnValue": "text",
"returnArray": false
},
{
"key": "productName",
"cssSelector": "h1, .product-title",
"returnValue": "text",
"returnArray": false
}
]
},
"options": {}
},
"type": "n8n-nodes-base.html",
"typeVersion": 1.2,
"position": [
512,
0
],
"id": "aw333333-3333-3333-3333-aw3333333304",
"name": "Extract Data"
},
{
"parameters": {
"jsCode": "// Get current and previous price from workflow static data\nconst staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\n\n// Parse numeric values for comparison\nconst parsePrice = (str) => {\n if (!str) return null;\n const match = str.match(/[\\d,]+\\.?\\d*/);\n return match ? parseFloat(match[0].replace(',', '')) : null;\n};\n\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\n\n// Update stored price\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\n\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\n\nreturn [{\n json: {\n productName,\n currentPrice,\n previousPrice: previousPrice || 'first check',\n changed,\n direction,\n diff: changed ? `$${diff}` : null,\n checkedAt: new Date().toISOString()\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
0
],
"id": "aw333333-3333-3333-3333-aw3333333305",
"name": "Compare Data"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "price-if-001",
"leftValue": "={{ $json.changed }}",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1104,
0
],
"id": "aw333333-3333-3333-3333-aw3333333306",
"name": "Data Changed?"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "alert-001",
"name": "alert",
"value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} → {{ $json.currentPrice }} ({{ $json.direction === 'dropped' ? '-' : '+' }}{{ $json.diff }})",
"type": "string"
},
{
"id": "alert-002",
"name": "severity",
"value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
"type": "string"
},
{
"id": "alert-003",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
-80
],
"id": "aw333333-3333-3333-3333-aw3333333307",
"name": "Build Alert"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "nc-001",
"name": "status",
"value": "no_change",
"type": "string"
},
{
"id": "nc-002",
"name": "currentPrice",
"value": "={{ $json.currentPrice }}",
"type": "string"
},
{
"id": "nc-003",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
128
],
"id": "aw333333-3333-3333-3333-aw3333333308",
"name": "No Change"
},
{
"parameters": {
"httpMethod": "POST",
"path": "price-monitor-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
420
],
"id": "aw333333-3333-3333-3333-aw3333333309",
"name": "Webhook Trigger",
"webhookId": "aw333333-aaaa-bbbb-cccc-aw3333333309",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "https://YOUR-TARGET-SITE.com/product-page",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
420
],
"id": "aw333333-3333-3333-3333-aw3333333310",
"name": "Solve AWS WAF [Webhook]",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"url": "https://YOUR-TARGET-SITE.com/product-page",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Cookie",
"value": "={{ $json.data.solution.cookie }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
420
],
"id": "aw333333-3333-3333-3333-aw3333333311",
"name": "Fetch Product Page [Webhook]"
},
{
"parameters": {
"operation": "extractHtmlContent",
"sourceData": "json",
"dataPropertyName": "data",
"extractionValues": {
"values": [
{
"key": "price",
"cssSelector": ".product-price, [data-price], .price",
"returnValue": "text",
"returnArray": false
},
{
"key": "productName",
"cssSelector": "h1, .product-title",
"returnValue": "text",
"returnArray": false
}
]
},
"options": {}
},
"type": "n8n-nodes-base.html",
"typeVersion": 1.2,
"position": [
512,
420
],
"id": "aw333333-3333-3333-3333-aw3333333312",
"name": "Extract Data [Webhook]"
},
{
"parameters": {
"jsCode": "// Get current and previous price from workflow static data\nconst staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\n\n// Parse numeric values for comparison\nconst parsePrice = (str) => {\n if (!str) return null;\n const match = str.match(/[\\d,]+\\.?\\d*/);\n return match ? parseFloat(match[0].replace(',', '')) : null;\n};\n\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\n\n// Update stored price\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\n\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\n\nreturn [{\n json: {\n productName,\n currentPrice,\n previousPrice: previousPrice || 'first check',\n changed,\n direction,\n diff: changed ? `$${diff}` : null,\n checkedAt: new Date().toISOString()\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
420
],
"id": "aw333333-3333-3333-3333-aw3333333313",
"name": "Compare Data [Webhook]"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "price-if-002",
"leftValue": "={{ $json.changed }}",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1104,
420
],
"id": "aw333333-3333-3333-3333-aw3333333314",
"name": "Data Changed? [Webhook]"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "alert-004",
"name": "alert",
"value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} → {{ $json.currentPrice }} ({{ $json.direction === 'dropped' ? '-' : '+' }}{{ $json.diff }})",
"type": "string"
},
{
"id": "alert-005",
"name": "severity",
"value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
"type": "string"
},
{
"id": "alert-006",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
340
],
"id": "aw333333-3333-3333-3333-aw3333333315",
"name": "Build Alert [Webhook]"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "nc-004",
"name": "status",
"value": "no_change",
"type": "string"
},
{
"id": "nc-005",
"name": "currentPrice",
"value": "={{ $json.currentPrice }}",
"type": "string"
},
{
"id": "nc-006",
"name": "checkedAt",
"value": "={{ $json.checkedAt }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1408,
548
],
"id": "aw333333-3333-3333-3333-aw3333333316",
"name": "No Change [Webhook]"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
1712,
420
],
"id": "aw333333-3333-3333-3333-aw3333333317",
"name": "Respond to Webhook [Webhook]"
}
],
"connections": {
"Every 6 Hours": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "Fetch Product Page",
"type": "main",
"index": 0
}
]
]
},
"Fetch Product Page": {
"main": [
[
{
"node": "Extract Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Data": {
"main": [
[
{
"node": "Compare Data",
"type": "main",
"index": 0
}
]
]
},
"Compare Data": {
"main": [
[
{
"node": "Data Changed?",
"type": "main",
"index": 0
}
]
]
},
"Data Changed?": {
"main": [
[
{
"node": "Build Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "No Change",
"type": "main",
"index": 0
}
]
]
},
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF [Webhook]": {
"main": [
[
{
"node": "Fetch Product Page [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Fetch Product Page [Webhook]": {
"main": [
[
{
"node": "Extract Data [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Extract Data [Webhook]": {
"main": [
[
{
"node": "Compare Data [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Compare Data [Webhook]": {
"main": [
[
{
"node": "Data Changed? [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Data Changed? [Webhook]": {
"main": [
[
{
"node": "Build Alert [Webhook]",
"type": "main",
"index": 0
}
],
[
{
"node": "No Change [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"Build Alert [Webhook]": {
"main": [
[
{
"node": "Respond to Webhook [Webhook]",
"type": "main",
"index": 0
}
]
]
},
"No Change [Webhook]": {
"main": [
[
{
"node": "Respond to Webhook [Webhook]",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Quy trình làm việc này tự động hóa việc gửi biểu mẫu đăng nhập được bảo vệ bằng AWS WAF từ đầu đến cuối. Nó giải quyết thử thách AWS WAF trước khi gửi thông tin đăng nhập.
Quy trình làm việc này bao gồm năm nút:
| Cài đặt | Giá trị |
|---|---|
| Phương thức HTTP | POST |
| Đường dẫn | login-aws-waf |
| Phản hồi | Response Node |
Điều này tạo một điểm cuối tại: https://your-n8n-instance.com/webhook/login-aws-waf
| Tham số | Giá trị |
|---|---|
| Thao tác | AWS WAF |
| URL trang web | https://YOUR-TARGET-SITE.com/login |
Cũng chọn thông tin xác thực CapSolver của bạn.
| Cài đặt | Giá trị |
|---|---|
| Phương thức | POST |
| URL | https://YOUR-TARGET-SITE.com/login |
| Loại nội dung | form-urlencoded |
| Tham số nội dung | username=YOUR_USERNAME, password=YOUR_PASSWORD, Cookie={{ $('Solve AWS WAF').item.json.data.solution.cookie }} |
Quan trọng: Đảm bảo thay thế
YOUR_USERNAMEvàYOUR_PASSWORDbằng thông tin đăng nhập thực tế. Ngoài ra, bạn có thể cần điều chỉnh tên trường biểu mẫu để khớp với HTML của trang web mục tiêu.
| Cài đặt | Giá trị |
|---|---|
| Phản hồi bằng | JSON |
| Nội dung phản hồi | ={{ JSON.stringify($json) }} |
Gửi yêu cầu POST đến điểm cuối webhook của bạn:
curl -X POST https://your-n8n-instance.com/webhook/login-aws-waf \
-H "Content-Type: application/json" \
-d '{
"websiteURL": "https://example.com/login",
"username": "testuser",
"password": "testpass"
}'
Phản hồi dự kiến (thành công):
{
"status": "success",
"message": "Login successful",
"solution": {
"cookie": "aws-waf-token=AQAAAA..."
}
}
Phản hồi dự kiến (thất bại):
{
"status": "failed",
"message": "Login failed: Invalid credentials or captcha",
"error": "..."
}
Sao chép JSON bên dưới và nhập vào n8n thông qua Menu -> Import from JSON:
{
"name": "AWS WAF Account Login — CapSolver + Schedule + Webhook",
"nodes": [
{
"parameters": {
"content": "## Tự động hóa đăng nhập tài khoản AWS WAF — CapSolver + Lịch trình + Webhook\n\n**Dành cho:** Các nhóm cần tự động hóa việc đăng nhập vào các tài khoản được bảo vệ bằng AWS WAF.\n\n**Chức năng:** Giải quyết thử thách AWS WAF, sau đó gửi biểu mẫu đăng nhập bằng cookie đã giải quyết và thông tin đăng nhập của người dùng.\n\n**Cách hoạt động:**\n1. Webhook kích hoạt luồng.\n2. CapSolver giải quyết thử thách AWS WAF.\n3. Yêu cầu HTTP gửi biểu mẫu đăng nhập bằng cookie đã giải quyết và thông tin đăng nhập của người dùng.\n4. Webhook phản hồi kết quả đăng nhập.\n\n**Thiết lập:**\n1. Thêm khóa API CapSolver của bạn trong **Settings → Credentials**.\n2. Thay thế URL giữ chỗ và thông tin đăng nhập.\n3. Điều chỉnh tên trường biểu mẫu để khớp với trang web mục tiêu của bạn.\n4. Kích hoạt quy trình làm việc.",
"height": 480,
"width": 460,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-728,
-400
],
"id": "sticky-blog-main-1773678228096-1",
"name": "Sticky Note"
},
{
"parameters": {
"httpMethod": "POST",
"path": "login-aws-waf",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-400,
0
],
"id": "aw444444-4444-4444-4444-aw4444444401",
"name": "Webhook Trigger",
"webhookId": "aw444444-aaaa-bbbb-cccc-aw4444444401",
"onError": "continueRegularOutput"
},
{
"parameters": {
"operation": "AWS WAF",
"type": "AntiAwsWafTaskProxyLess",
"websiteURL": "={{ $json.body.websiteURL }}",
"optional": {}
},
"type": "n8n-nodes-capsolver.capSolver",
"typeVersion": 1,
"position": [
-96,
0
],
"id": "aw444444-4444-4444-4444-aw4444444402",
"name": "Solve AWS WAF",
"credentials": {
"capSolverApi": {
"id": "YOUR_CREDENTIAL_ID",
"name": "CapSolver account"
}
}
},
{
"parameters": {
"method": "POST",
"url": "={{ $json.body.websiteURL }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
},
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded"
},
{
"name": "Cookie",
"value": "={{ $('Solve AWS WAF').item.json.data.solution.cookie }}}"
}
]
},
"sendBody": true,
"contentType": "form-urlencoded",
"bodyParameters": {
"parameters": [
{
"name": "username",
"value": "={{ $json.body.username }}"
},
{
"name": "password",
"value": "={{ $json.body.password }}"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": false
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
208,
0
],
"id": "aw444444-4444-4444-4444-aw4444444403",
"name": "Submit Login Form"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
512,
0
],
"id": "aw444444-4444-4444-4444-aw4444444404",
"name": "Respond to Webhook"
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Solve AWS WAF",
"type": "main",
"index": 0
}
]
]
},
"Solve AWS WAF": {
"main": [
[
{
"node": "Submit Login Form",
"type": "main",
"index": 0
}
]
]
},
"Submit Login Form": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Lỗi này có nghĩa là tài khoản hoặc gói CapSolver của bạn không bao gồm quyền truy cập AWS WAF. Vui lòng kiểm tra bảng điều khiển CapSolver của bạn để xác minh xem gói của bạn có bao gồm dịch vụ này không.
Lỗi này cho biết rằng tham số websiteURL bạn cung cấp trong nút CapSolver không chính xác. Vui lòng kiểm tra kỹ tab mạng của công cụ dành cho nhà phát triển của trang web mục tiêu để đảm bảo bạn đang sử dụng giá trị chính xác.
Nếu AWS WAF đã được giải quyết thành công nhưng đăng nhập vẫn không thành công, có thể có vấn đề với:
Lỗi này cho biết rằng khóa API CapSolver của bạn được định cấu hình trong n8n không chính xác hoặc đã hết hạn. Vui lòng kiểm tra bảng điều khiển CapSolver của bạn và cập nhật thông tin xác thực trong n8n.
websiteURL và bất kỳ tham số tùy chọn nào như awsKey, awsIv, awsContext, awsChallengeJS và awsApiJs là chính xác. Đây là chìa khóa để giải quyết AWS WAF thành công.Sẵn sàng bắt đầu? Đăng ký CapSolver và sử dụng mã thưởng n8n để nhận thêm 8% tiền thưởng cho lần nạp tiền đầu tiên của bạn!

Bạn đã học cách xây dựng API giải quyết AWS WAF và quy trình làm việc tự động hóa đăng nhập tài khoản bằng n8n và CapSolver.
Tóm tắt:
Sự phức tạp chính của AWS WAF nằm ở các thử thách vô hình và xác thực dựa trên cookie. Bằng cách xử lý đúng cookie aws-waf-token trong các yêu cầu HTTP, bạn có thể tự động hóa việc giải quyết AWS WAF một cách hiệu quả. Sau đó, bạn có thể tích hợp liền mạch các mã thông báo đã giải quyết này vào quy trình làm việc đăng nhập hoặc thu thập dữ liệu của mình.
Mẹo: Các quy trình làm việc này sử dụng trình kích hoạt Webhook, nhưng bạn có thể thay thế nút trình kích hoạt bằng bất kỳ trình kích hoạt n8n nào khác — thủ công, sự kiện ứng dụng, gửi biểu mẫu, v.v. Sau khi AWS WAF được giải quyết, hãy sử dụng các nút tích hợp của n8n để lưu kết quả vào Google Sheets, cơ sở dữ liệu, bộ nhớ đám mây hoặc gửi cảnh báo qua Telegram/Slack/email.
AWS WAF là tường lửa ứng dụng web cấp doanh nghiệp của Amazon bảo vệ các trang web khỏi lưu lượng bot và lạm dụng thông qua các thử thách vô hình và xác minh dựa trên mã thông báo.
AWS WAF không yêu cầu khóa trang web, thay vào đó sử dụng xác thực dựa trên cookie và trả về một cookie aws-waf-token. Nó thường là một thử thách vô hình không có tiện ích con hiển thị để người dùng tương tác.
Giá cả khác nhau tùy theo mức sử dụng. Vui lòng kiểm tra trang giá của CapSolver để biết giá AWS WAF hiện tại. Các tác vụ giải quyết AWS WAF thường đắt hơn nhận dạng hình ảnh thành văn bản đơn giản, nhưng rẻ hơn một số loại CAPTCHA phức tạp khác.
Các tác vụ giải quyết AWS WAF thường mất 10-30 giây, tùy thuộc vào độ phức tạp của thử thách và tải máy chủ CapSolver. Không giống như ImageToTextTask, việc giải quyết AWS WAF liên quan đến việc tạo tác vụ và thăm dò, vì vậy nó không tức thì.
Dịch vụ giải quyết AWS WAF của CapSolver thường không yêu cầu bạn cung cấp proxy. CapSolver xử lý các yêu cầu proxy nội bộ. Bạn chỉ cần cung cấp websiteURL và bất kỳ tham số tùy chọn nào.
aws-waf-token của tôi không được chấp nhận?Nếu aws-waf-token không được chấp nhận, vui lòng kiểm tra những điều sau:
awsKey, awsIv, v.v., hãy đảm bảo bạn đã cung cấp chúng một cách chính xác.Nếu AWS WAF đã được giải quyết thành công nhưng đăng nhập vẫn không thành công, vui lòng kiểm tra những điều sau:
Có. Quy trình làm việc này hoạt động với cả n8n tự lưu trữ và n8n Cloud. Nút CapSolver đã có sẵn dưới dạng tích hợp chính thức; bạn chỉ cần thêm thông tin xác thực API của mình.
Xây dựng API giải eCAPTCHA v2/v3 bằng CapSolver và n8n. Tìm hiểu cách tự động hóa việc giải token, gửi token đến website và trích xuất dữ liệu được bảo vệ mà không cần lập trình.

Hãy tìm hiểu cách tích hợp CapSolver với n8n để giải quyết bài toán GeeTest V3 và xây dựng các quy trình tự động hóa đáng tin cậy.
