Quay lại danh sách
Xây dựng Scraper Tin Đáng Tin Cậy: Xử Lý Giới Hạn Tốc Độ và CAPTCHA

Xây dựng Scraper Tin Đáng Tin Cậy: Xử Lý Giới Hạn Tốc Độ và CAPTCHA

24 tháng 6, 2026

Giới thiệu

Trong thế giới dữ liệu mở, scraper là công cụ không thể thiếu cho các nhà dữ liệu, marketer và nhà phát triển. Tuy nhiên, việc xây dựng một scraper tin cậy không chỉ là thu thập dữ liệu qua HTTP, mà còn phải đối phó với hai thách thức lớn:

  1. Giới hạn tốc độ (rate limiting) – Nhiều website áp dụng các chiến lược chặn IP hoặc giới hạn số lần truy cập trong một khoảng thời gian.
  2. CAPTCHA – Hệ thống bảo vệ chống bot, làm khó khăn cho việc tự động hóa.

Bài viết này sẽ cung cấp một khung thực tiếp để xây dựng scraper linh hoạt, bao gồm lựa chọn proxy, quản lý session, xử lý lỗi và phát hiện CAPTCHA, cùng các đoạn mã mẫu bằng Python.

1. Xác định mục tiêu và kế hoạch

  • Định dạng dữ liệu: JSON, CSV hay database?
  • Tần suất crawl: một lần, hàng giờ, hàng ngày?
  • Đối tượng mục tiêu: trang sản phẩm, bài viết, dữ liệu người dùng?

Những quyết định này sẽ quyết định cách bạn cấu hình proxy, session và logic xử lý.

2. Chọn loại proxy phù hợp

Kiểu proxy Ưu điểm Nhược điểm Ứng dụng
Residential Giảm khả năng bị chặn Giá cao, tốc độ thay đổi Scrape dữ liệu nhạy cảm, tránh IP block
Datacenter Mạnh mẽ, giá rẻ Dễ bị phát hiện Crawl dữ liệu công khai, test
Mobile Độ tin cậy cao Hạn chế băng thông Crawl dịch vụ mobile-first
  • Xử lý xoay vòng: Sử dụng thư viện ProxyPool hoặc dịch vụ của RoProxy để tự động thay đổi IP.
  • Sticky session: Đối với trang cần login, giữ một IP ổn định cho mỗi session.

3. Xây dựng session và quản lý yêu cầu

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# Thiết lập retry
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=frozenset(['GET', 'POST'])
)
adapter = HTTPAdapter(max_retries=retry_strategy)

# Tạo session
session = requests.Session()
session.mount("https://", adapter)
session.mount("http://", adapter)

# Thiết lập proxy
proxy = {
    'http': 'http://user:[email protected]:8080',
    'https': 'http://user:[email protected]:8080'
}
  • Retry giúp tự động thử lại khi gặp lỗi 429 (Too Many Requests) hoặc lỗi server.
  • Giữ session tối ưu cho các request liên tiếp, giúp reuse TCP connections.

4. Phát hiện và xử lý CAPTCHA

4.1 Phát hiện

  • Kiểm tra mã trạng thái HTTP (thường 200 nhưng nội dung chứa biểu mẫu CAPTCHA).
  • Kiểm tra chuỗi HTML: div có id captcha, img chứa dữ liệu src chứa captcha.

4.2 Giải quyết

Phương pháp Khi nào dùng Cách triển khai
Tự động ngồi chờ Trên mức giới hạn time.sleep() + tăng độ trễ ngẫu nhiên
Sử dụng captcha solver Phải vượt qua Dịch vụ 2captcha, anti-captcha
Thay đổi User-Agent, header Tránh phát hiện Thêm User-Agent, Accept-Language
from time import sleep
import random

# Giả sử response chứa CAPTCHA
if 'captcha' in response.text.lower():
    delay = random.randint(30, 60)  # Ngủ 30-60s
    sleep(delay)
    # Cập nhật headers
    session.headers.update({'User-Agent': random_user_agent()})

5. Quản lý tốc độ và giới hạn

5.1 Đặt giới hạn tốc độ

  • Sử dụng asyncioaiohttp cho scraper đa luồng.
  • Đặt asyncio.Semaphore để giới hạn số lượng request đồng thời.
import asyncio
import aiohttp

semaphore = asyncio.Semaphore(5)  # 5 request đồng thời

async def fetch(url):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as resp:
                return await resp.text()

5.2 Thêm delay ngẫu nhiên

import random
import time

for url in urls:
    delay = random.uniform(1, 3)  # 1-3 giây
    time.sleep(delay)
    # Gửi request

6. Xử lý dữ liệu và lưu trữ

  • Dùng BeautifulSoup hoặc lxml để parse DOM.
  • Lưu dữ liệu vào CSV, SQLite hoặc MongoDB tùy nhu cầu.
from bs4 import BeautifulSoup
import csv

soup = BeautifulSoup(html, 'html.parser')
items = soup.select('.product')
with open('data.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['id', 'name', 'price'])
    for item in items:
        writer.writerow([item['data-id'], item.text.strip(), item.get('price')])

7. Kiểm tra, ghi log và cảnh báo

  • Ghi log với logging module.
  • Siêu cảnh báo khi gặp lỗi 429 nhiều lần hoặc CAPTCHA liên tục.
  • Sử dụng Sentry hoặc Rollbar để theo dõi lỗi.

8. Thực hành: Scraper mẫu

import requests, time, random
from bs4 import BeautifulSoup

proxy_url = 'http://user:[email protected]:8080'
proxies = {'http': proxy_url, 'https': proxy_url}
headers = {'User-Agent': 'Mozilla/5.0'}

def get_page(url):
    for _ in range(3):
        resp = requests.get(url, headers=headers, proxies=proxies, timeout=10)
        if resp.status_code == 200 and 'captcha' not in resp.text.lower():
            return resp.text
        elif resp.status_code == 429:
            sleep_time = random.randint(30, 60)
            time.sleep(sleep_time)
    return None

urls = ['https://example.com/page/{}'.format(i) for i in range(1, 101)]
for url in urls:
    html = get_page(url)
    if html:
        soup = BeautifulSoup(html, 'html.parser')
        # ... parse logic ...
    time.sleep(random.uniform(1, 3))

9. Kết luận

  • Proxy: Lựa chọn đúng loại và xoay vòng IP là yếu tố quyết định.
  • Retry + Delay: Giúp vượt qua rate limiting mà không bị chặn mãn mã.
  • Captcha handling: Sự kết hợp giữa chờ, thay đổi header và dịch vụ giải mã.
  • Ghi log: Phụng thuyết giúp phát hiện nhanh lỗi.

Bằng cách áp dụng những phương pháp trên, bạn có thể xây dựng một scraper mạnh mẽ, ít bị chặn, và tuân thủ quy tắc của website. Đây là nền tảng vững chắc để phát triển các ứng dụng thu thập dữ liệu chuyên nghiệp.