Quay lại blog

Cách giảm tỷ lệ cấm khi web scraping xuống 5%: 12 phương pháp bảo vệ đã được kiểm chứng

Phân tích 12 phương pháp đã được kiểm chứng để giảm tỷ lệ ban khi thu thập dữ liệu: từ cài đặt proxy đến giả lập hành vi của người dùng thực. Ví dụ thực tiễn và giải pháp sẵn có.

📅10 tháng 2, 2026
```html

Nếu bạn đang thu thập dữ liệu từ các sàn thương mại điện tử, giám sát giá đối thủ hoặc thu thập dữ liệu từ các trang web, bạn sẽ biết vấn đề này: các trang web chặn địa chỉ IP, yêu cầu captcha hoặc trả về trang trống. Tỷ lệ cấm (ban rate - phần trăm yêu cầu bị chặn) có thể đạt 70-90%, khiến việc phân tích cú pháp trở nên không thể. Trong bài viết này, chúng ta sẽ phân tích các phương pháp cụ thể giúp giảm tỷ lệ cấm xuống 5-10% và thu thập dữ liệu một cách ổn định.

Chúng ta sẽ xem xét cả các giải pháp kỹ thuật (luân chuyển proxy, tiêu đề HTTP, fingerprinting) và các mẫu hành vi (độ trễ, mô phỏng hành động người dùng). Tất cả các phương pháp đã được kiểm chứng trong thực tế khi phân tích cú pháp Wildberries, Ozon, Avito và các nền tảng nước ngoài.

Tại sao các trang web chặn trình phân tích cú pháp: các yếu tố kích hoạt chính

Trước khi phân tích các phương pháp bảo vệ, điều quan trọng là phải hiểu cách các trang web xác định lưu lượng tự động. Các hệ thống chống bot hiện đại (Cloudflare, Akamai, DataDome, Imperva) phân tích hàng chục tham số của mỗi yêu cầu. Dưới đây là các yếu tố kích hoạt chặn chính:

Yếu tố kích hoạt ở cấp mạng:

  • Quá nhiều yêu cầu từ một địa chỉ IP (ví dụ: hơn 100 yêu cầu mỗi phút)
  • IP từ các dải trung tâm dữ liệu đã biết (AWS, Google Cloud, Hetzner)
  • Không khớp về địa lý: IP từ Nga yêu cầu phiên bản tiếng Anh của trang web
  • Thiếu bản ghi DNS ngược cho địa chỉ IP

Yếu tố kích hoạt ở cấp HTTP:

  • Thiếu hoặc sai tiêu đề HTTP (User-Agent, Accept-Language, Referer)
  • Thứ tự tiêu đề khác với tiêu chuẩn của trình duyệt
  • Phiên bản TLS/SSL không tương ứng với trình duyệt được khai báo
  • Thiếu cookies hoặc sử dụng không đúng cách

Yếu tố kích hoạt ở cấp trình duyệt (JavaScript):

  • Không thực thi JavaScript (nếu sử dụng HTTP client đơn giản)
  • Browser fingerprinting: Canvas, WebGL, AudioContext, phông chữ đã cài đặt
  • Không có chuyển động chuột, cuộn trang, nhấp chuột
  • Kích thước cửa sổ trình duyệt (trình duyệt headless thường có kích thước không chuẩn)
  • Có dấu hiệu tự động hóa: thuộc tính navigator.webdriver, window.chrome

Yếu tố kích hoạt hành vi:

  • Điều hướng quá nhanh giữa các trang (dưới 1 giây)
  • Khoảng thời gian giống nhau giữa các yêu cầu (ví dụ: đúng mỗi 2 giây)
  • Duyệt trang tuần tự (1, 2, 3, 4...) không bỏ qua
  • Thiếu các hành động điển hình của người dùng: tìm kiếm, bộ lọc, xem hình ảnh

Ví dụ, khi phân tích cú pháp Wildberries, lỗi điển hình là gửi yêu cầu mỗi 0.5 giây từ một IP. Hệ thống chống bot Cloudflare sẽ ngay lập tức xác định mẫu và chặn IP trong 24 giờ. Người dùng thực tế mất 5-15 giây để xem thẻ sản phẩm, cuộn trang, nhấp vào hình ảnh.

Luân chuyển proxy: cách thay đổi địa chỉ IP đúng cách

Sử dụng proxy là phương pháp cơ bản để giảm tỷ lệ cấm. Nhưng điều quan trọng không chỉ là mua proxy mà còn phải cấu hình luân chuyển đúng cách. Dưới đây là các chiến lược đã được kiểm chứng:

Lựa chọn loại proxy cho phân tích cú pháp

Loại proxy Tỷ lệ cấm Tốc độ Khi nào sử dụng
Proxy trung tâm dữ liệu Cao (40-60%) Rất cao Các trang web đơn giản không có bảo vệ, phân tích cú pháp hàng loạt với nhóm IP lớn
Proxy dân cư Thấp (5-15%) Trung bình Sàn thương mại điện tử (Wildberries, Ozon), trang web có Cloudflare, mạng xã hội
Proxy di động Rất thấp (2-8%) Thấp Trang web có bảo vệ mạnh, phiên bản di động của ứng dụng

Để phân tích cú pháp các sàn thương mại điện tử (Wildberries, Ozon, Avito), nên sử dụng proxy dân cư — chúng có IP của người dùng gia đình thực tế, khó phân biệt với lưu lượng thông thường. Proxy trung tâm dữ liệu phù hợp cho các trang web ít được bảo vệ hơn hoặc khi cần tốc độ tối đa với khối lượng dữ liệu lớn.

Chiến lược luân chuyển địa chỉ IP

Chiến lược 1: Luân chuyển theo thời gian

Thay đổi IP mỗi 5-10 phút. Đây là sự cân bằng tối ưu: đủ lâu để không gây nghi ngờ do thay đổi thường xuyên, nhưng đủ thường xuyên để không tích lũy lịch sử yêu cầu trên một IP.

Ví dụ: Khi phân tích cú pháp danh mục 1000 sản phẩm với khoảng cách 3 giây giữa các yêu cầu, một IP sẽ hoạt động khoảng 100 yêu cầu, sau đó thay đổi.

Chiến lược 2: Luân chuyển theo số lượng yêu cầu

Thay đổi IP sau 50-150 yêu cầu. Điều này giúp tránh tích lũy hoạt động đáng ngờ trên một địa chỉ. Thêm tính ngẫu nhiên: không phải đúng 100 yêu cầu mà từ 80 đến 120.

Ví dụ: Cấu hình script để sau một số yêu cầu ngẫu nhiên (80-120) sẽ luân chuyển proxy từ nhóm.

Chiến lược 3: Sticky sessions (proxy phiên)

Đối với các trang web yêu cầu xác thực hoặc làm việc với giỏ hàng, sử dụng sticky sessions — cố định IP trong thời gian phiên (10-30 phút). Điều này cho phép lưu cookies và không gây nghi ngờ khi thay đổi IP trong cùng một phiên.

Ví dụ: Khi phân tích cú pháp tài khoản cá nhân trên Ozon, sử dụng một IP để đăng nhập và tất cả các yêu cầu tiếp theo trong phiên 15 phút.

Quan trọng: Không sử dụng cùng một IP cho các nhiệm vụ khác nhau. Nếu IP bị chặn khi phân tích cú pháp một trang web, đừng sử dụng ngay cho trang khác — đợi 24-48 giờ.

Kích thước nhóm proxy

Kích thước nhóm tối thiểu phụ thuộc vào cường độ phân tích cú pháp:

  • Cường độ thấp (đến 10.000 yêu cầu mỗi ngày): 10-20 proxy
  • Cường độ trung bình (10.000 - 100.000 yêu cầu mỗi ngày): 50-100 proxy
  • Cường độ cao (hơn 100.000 yêu cầu mỗi ngày): 200+ proxy hoặc proxy dân cư với luân chuyển tự động

Đối với proxy dân cư có luân chuyển trên mỗi yêu cầu (rotating proxies), kích thước nhóm có thể nhỏ hơn vì nhà cung cấp tự động thay thế IP mới từ nhóm hàng triệu địa chỉ của họ.

User-Agent và tiêu đề HTTP: mô phỏng trình duyệt thực

Ngay cả với proxy tốt, bạn vẫn có thể bị chặn nếu tiêu đề HTTP trông đáng ngờ. Các trang web phân tích không chỉ User-Agent mà còn thứ tự tiêu đề, giá trị của chúng và sự tương ứng với nhau.

User-Agent đúng

Không sử dụng cùng một User-Agent cho tất cả các yêu cầu. Tạo danh sách các trình duyệt phổ biến và chọn ngẫu nhiên từ đó:

user_agents = [
    # Chrome trên Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    # Chrome trên macOS
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    # Firefox trên Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
    # Safari trên macOS
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
    # Edge trên Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
]

Lỗi: Sử dụng phiên bản trình duyệt cũ (ví dụ: Chrome 80) — điều này sẽ ngay lập tức gây nghi ngờ. Cập nhật danh sách User-Agent mỗi 2-3 tháng, theo dõi các phiên bản hiện tại trên trang whatismybrowser.com.

Bộ tiêu đề HTTP đầy đủ

Các trình duyệt hiện đại gửi 15-20 tiêu đề. Dưới đây là bộ tối thiểu cần thiết để mô phỏng Chrome:

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "DNT": "1",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Cache-Control": "max-age=0",
    "sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"'
}

Lưu ý các tiêu đề Sec-Fetch-*sec-ch-ua-* — chúng xuất hiện trong các phiên bản mới của Chrome và sự vắng mặt của chúng có thể tiết lộ tự động hóa.

Thứ tự tiêu đề quan trọng

Các trình duyệt gửi tiêu đề theo thứ tự nhất định. Ví dụ, Chrome luôn đặt Host đầu tiên, sau đó Connection, User-Agent và tiếp tục. Nếu bạn sử dụng thư viện Python requests, thứ tự có thể theo bảng chữ cái, điều này sẽ tiết lộ tự động hóa.

Giải pháp: sử dụng các thư viện tạo tiêu đề đúng cách (curl_cffi cho Python, got cho Node.js) hoặc trình duyệt headless (Puppeteer, Playwright, Selenium), tạo tiêu đề như trình duyệt thực.

Độ trễ giữa các yêu cầu: khoảng thời gian tối ưu

Một trong những phương pháp đơn giản nhưng hiệu quả nhất để giảm tỷ lệ cấm là độ trễ đúng giữa các yêu cầu. Người dùng thực không thể mở 10 trang trong một giây, vì vậy các yêu cầu quá nhanh ngay lập tức gây ra chặn.

Độ trễ ngẫu nhiên thay vì cố định

Không sử dụng độ trễ cố định (ví dụ: đúng 2 giây giữa các yêu cầu). Các hệ thống chống bot dễ dàng xác định mẫu như vậy. Sử dụng khoảng thời gian ngẫu nhiên:

import random
import time

# Thay vì độ trễ cố định
time.sleep(2)  # ❌ Không tốt

# Sử dụng khoảng thời gian ngẫu nhiên
delay = random.uniform(2.5, 5.5)  # ✅ Tốt
time.sleep(delay)

Khoảng thời gian được khuyến nghị cho các trang web khác nhau

Loại trang web Độ trễ tối thiểu Độ trễ được khuyến nghị Ví dụ
Sàn thương mại điện tử có bảo vệ 3-5 giây 5-10 giây Wildberries, Ozon, Lamoda
Bảng rao vặt 2-4 giây 4-8 giây Avito, Yula, CIAN
Trang tin tức 1-2 giây 2-4 giây RBC, Kommersant, Vedomosti
API không giới hạn 0.5-1 giây 1-2 giây API mở, nguồn cấp RSS

Độ trễ thích ứng dựa trên phản hồi máy chủ

Cách tiếp cận nâng cao — thay đổi độ trễ động dựa trên phản hồi máy chủ:

base_delay = 3.0  # Độ trễ cơ bản
delay_multiplier = 1.0

response = requests.get(url, headers=headers, proxies=proxies)

# Nếu nhận được captcha hoặc 429 — tăng độ trễ
if response.status_code == 429 or 'captcha' in response.text.lower():
    delay_multiplier *= 1.5
    print(f"Phát hiện bảo vệ, tăng độ trễ lên {base_delay * delay_multiplier}s")

# Nếu mọi thứ ổn — có thể tăng tốc một chút
elif response.status_code == 200:
    delay_multiplier = max(1.0, delay_multiplier * 0.95)

time.sleep(random.uniform(base_delay * delay_multiplier, base_delay * delay_multiplier * 1.5))

Cách tiếp cận này cho phép tự động làm chậm khi phát hiện bảo vệ và tăng tốc khi trang web không có phản ứng mạnh.

Bảo vệ chống fingerprinting: Canvas, WebGL, phông chữ

Nếu trang web sử dụng JavaScript để kiểm tra, các tiêu đề HTTP đơn giản là không đủ. Các hệ thống chống bot hiện đại tạo "dấu vân tay" trình duyệt (fingerprint) dựa trên hàng chục tham số: Canvas, WebGL, phông chữ đã cài đặt, múi giờ, độ phân giải màn hình và các tham số khác.

Các tham số fingerprinting chính

Canvas fingerprinting

Trang web vẽ hình ảnh vô hình trong Canvas và đọc nó. Các trình duyệt và hệ điều hành khác nhau render hình ảnh khác nhau, tạo ra dấu vân tay duy nhất. Trình duyệt headless thường tạo Canvas giống nhau, điều này tiết lộ tự động hóa.

WebGL fingerprinting

Tương tự Canvas, nhưng sử dụng render 3D. Thông tin về card đồ họa, driver, tiện ích mở rộng được hỗ trợ được đọc. Trình duyệt headless thường hiển thị render phần mềm (SwiftShader) thay vì GPU thực.

Phông chữ đã cài đặt

JavaScript có thể xác định danh sách phông chữ đã cài đặt. Trình duyệt headless thường có bộ phông chữ hệ thống tối thiểu, khác với người dùng thực có cài đặt Microsoft Office, Adobe và các chương trình khác.

Thuộc tính Navigator

Các thuộc tính navigator.webdriver, navigator.plugins, navigator.languages tiết lộ tự động hóa. Ví dụ, trong Selenium navigator.webdriver === true, điều này ngay lập tức được xác định bởi các hệ thống chống bot.

Công cụ để vượt qua fingerprinting

Để vượt qua fingerprinting, sử dụng các công cụ chuyên dụng:

  • Undetected ChromeDriver (Python) — phiên bản Selenium đã sửa đổi, ẩn dấu hiệu tự động hóa
  • Puppeteer Stealth (Node.js) — plugin cho Puppeteer, thay thế tham số fingerprint
  • Playwright với stealth — tương tự Puppeteer, nhưng hỗ trợ tốt hơn các trình duyệt khác nhau
  • Trình duyệt chống phát hiện (Dolphin Anty, AdsPower, Multilogin) — cho những người không muốn viết code, các trình duyệt này tự động thay thế fingerprint

Ví dụ sử dụng undetected-chromedriver trong Python:

import undetected_chromedriver as uc

# Tạo trình duyệt với bảo vệ chống phát hiện
options = uc.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')

driver = uc.Chrome(options=options)
driver.get('https://example.com')

# Kiểm tra navigator.webdriver === undefined
webdriver_status = driver.execute_script("return navigator.webdriver")
print(f"navigator.webdriver: {webdriver_status}")  # Phải là None/undefined

Quản lý cookies và phiên làm việc

Nhiều trang web sử dụng cookies để theo dõi hành vi người dùng. Quản lý cookies đúng cách giúp tránh chặn và trông giống người dùng thực.

Lưu và tái sử dụng cookies

Thay vì tạo phiên mới cho mỗi yêu cầu, lưu cookies và sử dụng lại. Điều này mô phỏng hành vi người dùng thực quay lại trang web:

import requests
import pickle

session = requests.Session()

# Lần truy cập đầu tiên — nhận cookies
response = session.get('https://example.com')

# Lưu cookies vào file
with open('cookies.pkl', 'wb') as f:
    pickle.dump(session.cookies, f)

# Sau đó tải cookies
with open('cookies.pkl', 'rb') as f:
    session.cookies.update(pickle.load(f))

# Bây giờ các yêu cầu trông như từ người dùng quay lại
response = session.get('https://example.com/catalog')

Khởi động phiên trước khi phân tích cú pháp

Không bắt đầu phân tích cú pháp ngay từ các trang mục tiêu. Mô phỏng hành vi người dùng thực:

  1. Mở trang chủ của trang web
  2. Đợi 2-5 giây
  3. Mở trang danh mục hoặc phần
  4. Đợi 3-7 giây
  5. Chỉ sau đó mới bắt đầu phân tích cú pháp các trang mục tiêu

Điều này tạo lịch sử hoạt động trong cookies và giảm khả năng bị chặn.

Xử lý session cookies và token

Một số trang web tạo token duy nhất khi truy cập lần đầu và kiểm tra chúng trong các yêu cầu tiếp theo. Ví dụ, Wildberries sử dụng token trong tiêu đề x-requested-with. Luôn lưu các token như vậy từ phản hồi đầu tiên và gửi chúng trong các yêu cầu tiếp theo.

Render JavaScript: khi nào cần thiết

Nhiều trang web hiện đại tải nội dung qua JavaScript. Nếu bạn sử dụng HTTP client đơn giản (requests trong Python, axios trong Node.js), bạn sẽ nhận được trang trống hoặc placeholder. Trong những trường hợp như vậy, cần render JavaScript.

Khi nào cần render JavaScript

  • Trang web sử dụng React, Vue, Angular — nội dung được tải sau khi tải trang ban đầu
  • Dữ liệu được tải qua yêu cầu AJAX/Fetch
  • Trang web yêu cầu thực thi JavaScript để tạo token hoặc cookies
  • Có bảo vệ chống bot yêu cầu thực thi mã JS (ví dụ: Cloudflare Challenge)

Công cụ để render JavaScript

Công cụ Ngôn ngữ Tốc độ Vượt qua bảo vệ
Selenium Python, Java, C# Chậm Trung bình (với undetected-chromedriver)
Puppeteer Node.js Trung bình Tốt (với puppeteer-extra-plugin-stealth)
Playwright Python, Node.js, Java Nhanh Xuất sắc
Splash HTTP API Trung bình Yếu

Đối với hầu hết các nhiệm vụ, nên sử dụng Playwright — nó nhanh hơn Selenium, vượt qua bảo vệ tốt hơn và có API thuận tiện hơn.

Phương án thay thế: chặn yêu cầu API

Thường có thể tránh render JavaScript nếu tìm được các yêu cầu API mà trang web sử dụng để tải dữ liệu. Mở DevTools (F12) → tab Network → bộ lọc XHR/Fetch và xem trang web gửi những yêu cầu nào. Sau đó lặp lại các yêu cầu này trực tiếp qua HTTP client.

Ví dụ: Wildberries tải dữ liệu sản phẩm qua API https://catalog.wb.ru/catalog/.... Thay vì render toàn bộ trang, có thể yêu cầu API này trực tiếp, nhanh hơn 10-20 lần.

Vượt qua captcha: giải pháp tự động

Ngay cả với proxy và tiêu đề đúng, bạn vẫn có thể gặp captcha. Có một số cách tiếp cận để giải quyết nó:

Các loại captcha và phương pháp giải quyết

reCAPTCHA v2 (ô "Tôi không phải robot")

Được giải quyết qua dịch vụ nhận dạng: 2Captcha, Anti-Captcha, CapMonster. Chi phí: $1-3 cho 1000 lần giải. Thời gian giải: 10-30 giây.

reCAPTCHA v3 (vô hình, dựa trên điểm)

Phức tạp hơn. Phân tích hành vi người dùng và cho điểm từ 0 đến 1. Vượt qua: sử dụng trình duyệt headless với fingerprint đúng + mô phỏng hành động người dùng (di chuyển chuột, nhấp chuột).

hCaptcha

Tương tự reCAPTCHA, được sử dụng trên nhiều trang web. Được giải quyết qua cùng dịch vụ nhận dạng. Chi phí: $0.5-2 cho 1000 lần giải.

Cloudflare Challenge

JavaScript-challenge kiểm tra trình duyệt. Vượt qua: sử dụng thư viện chuyên dụng (cloudscraper cho Python, cloudflare-scraper cho Node.js) hoặc dịch vụ (FlareSolverr).

Tích hợp dịch vụ nhận dạng captcha

Ví dụ tích hợp 2Captcha trong Python:

from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

try:
    # Giải reCAPTCHA v2
    result = solver.recaptcha(
        sitekey='6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
        url='https://example.com'
    )
    
    # Nhận token giải pháp
    captcha_token = result['code']
    
    # Gửi form với token
    response = requests.post('https://example.com/submit', data={
        'g-recaptcha-response': captcha_token
    })
    
except Exception as e:
    print(f"Lỗi giải captcha: {e}")

Quan trọng: Giải captcha làm chậm phân tích cú pháp 10-30 lần và tăng chi phí. Chỉ sử dụng khi các phương pháp khác không hiệu quả. Trước tiên hãy thử cải thiện proxy, fingerprint và độ trễ.

Giới hạn tốc độ: cách không vượt quá giới hạn của trang web

Nhiều trang web có giới hạn rõ ràng hoặc ngầm định về số lượng yêu cầu. Vượt quá các giới hạn này dẫn đến chặn IP tạm thời hoặc vĩnh viễn.

Xác định giới hạn của trang web

Chú ý đến các tiêu đề HTTP trong phản hồi máy chủ:

  • X-RateLimit-Limit — số lượng yêu cầu tối đa trong khoảng thời gian
  • X-RateLimit-Remaining — còn bao nhiêu yêu cầu
  • X-RateLimit-Reset — khi nào giới hạn được đặt lại (Unix timestamp)
  • Retry-After — sau bao nhiêu giây có thể thử lại yêu cầu

Nếu bạn nhận được mã trạng thái 429 (Too Many Requests), điều này có nghĩa là vượt quá giới hạn. Đọc tiêu đề Retry-After và đợi thời gian được chỉ định trước yêu cầu tiếp theo.

Triển khai rate limiter

Tạo cơ chế kiểm soát tốc độ yêu cầu:

```