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:
- 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.
- 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
ProxyPoolhoặ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'
}
Retrygiúp tự động thử lại khi gặp lỗi 429 (Too Many Requests) hoặc lỗi server.- Giữ
sessiontố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:
divcó idcaptcha,imgchứa dữ liệusrcchứacaptcha.
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
asynciovàaiohttpcho 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
BeautifulSouphoặclxmlđể 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
loggingmodule. - 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
SentryhoặcRollbarđể 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.