Quay lại danh sách
Cách chọn proxy cho scraper Python không bị chặn

Cách chọn proxy cho scraper Python không bị chặn

20 tháng 10, 2026

Tại sao việc chọn proxy đúng với scraper Python lại quan trọng

Khi scraper Python gửi hàng trăm hoặc hàng ngàn yêu cầu đến cùng một máy chủ, IP gốc của bạn sẽ nhanh chóng bị đưa vào danh sách chặn (blacklist). Proxy giúp ẩn IP thật và phân phát tải đều qua nhiều IP, nhưng không phải loại proxy nào cũng phù hợp với mọi trường hợp. Lựa chọn sai proxy — ví dụ dùng residential proxy cho trang không kiểm tra địa lý, hoặc dùng datacenter proxy cho trang chặn proxy rộng rãi — sẽ khiến thời gian phát triển và duy trì scraper tăng lên đáng kể.

Dưới đây là quy trình cụ thể để chọn proxy phù hợp, từ xác định nhu cầu cho đến cấu hình chi tiết trong Python.

Xác định nhu cầu thực tế của scraper

Xác định mục tiêu thu thập

Trước khi chọn proxy, hãy trả lời nhanh các câu hỏi sau:

  • Số lượng yêu cầu: Dưới 1000 yêu cầu/ngày có thể dùng IP gốc, nhưng từ 5000 trở lên cần proxy.
  • Tần suất: Gửi 1 yêu cầu/giây thấp nguy cơ chặn, còn 10 yêu cầu/giây cần proxy rotating để luân phiên IP.
  • Trang mục tiêu: Trang có kiểm tra địa lý (geo-fencing) thì cần residential proxy ở quốc gia đúng.
  • Thời gian chạy: Scraper chạy liên tục 24/7 cần cấu hình sticky session để tránh thay đổi IP giữa các request trong một phiên.

Ví dụ thực tế

Một công ty thu thập giá sản phẩm từ Shopee và Tiki mỗi 10 phút một lần với 200 URL. Vì hai trang này thường xuyên cập nhật mã CAPTCHA và kiểm tra địa lý Việt Nam, nên cần:

  • Loại proxy: Residential proxy tại Việt Nam.
  • Chế độ xoay: Sticky session trong vòng 5 phút để duy trì phiên đăng nhập.
  • Tốc độ: Ít nhất 20 IP để tránh rate limit.

Hiểu rõ các loại proxy và đặc điểm

Loại proxy Đặc điểm Phù hợp với Rủi ro
Datacenter Tốc độ cao, giá rẻ, dễ bị chặn Trang không kiểm tra địa lý Dễ bị block
Residential IP thật từ người dùng, khó bị chặn Trang có kiểm tra địa lý Giá cao
Mobile IP từ SIM thật, khó nhận biết Trang chặn proxy tổng thể Rất đắt
ISP Kết hợp giữa datacenter và residential Cân bằng tốc độ và độ tin cậy Hạn chế nhà cung cấp

Khi nào dùng Datacenter

Datacenter proxy phù hợp cho các trường hợp sau:

  • Thu thập dữ liệu từ API công cộng không có cơ chế chặn.
  • Kiểm tra tốc độ tải trang.
  • Phát triển và test ban đầu.

Lưu ý: Trước khi mua gói datacenter, hãy kiểm tra trước 1 IP bằng cách gửi request đến trang mục tiêu để chắc chắn chưa bị chặn.

Khi nào chuyển sang Residential

Nếu scraper nhận được lỗi 403, 429 hoặc CAPTCHA liên tục, đã đến lúc chuyển sang residential proxy. Tuy nhiên, residential proxy có giá cao hơn nên nên dùng kết hợp với rotating proxy để tối ưu chi phí.

Cấu hình HTTP(S) proxy trong Python requests

Cách cơ bản

import requests

proxies = {
    "http": "http://user:pass@proxy_ip:port",
    "https": "https://user:pass@proxy_ip:port",
}

response = requests.get("https://example.com", proxies=proxies)
print(response.status_code)

Cấu hình authentication

Nhiều dịch vụ proxy yêu cầu xác thực qua username và password. Cách truyền trực tiếp trong URL có thể gây lỗi với một số proxy, nên nên dùng cách sau:

from requests.auth import HTTPProxyAuth

proxies = {
    "http": "http://proxy_ip:port",
    "https": "https://proxy_ip:port",
}

auth = HTTPProxyAuth("username", "password")
response = requests.get("https://example.com", proxies=proxies, auth=auth)

Sử dụng session để tận dụng sticky proxy

Để duy trì cùng một IP trong một phiên làm việc (sticky session), hãy sử dụng requests.Session():

import requests

session = requests.Session()
session.proxies.update({
    "http": "http://user:pass@proxy_ip:port",
    "https": "https://user:pass@proxy_ip:port",
})

# Các request sau sẽ dùng cùng một proxy
for url in urls:
    response = session.get(url)

Rotating proxy: cách xoay IP tự động

Tại sao cần rotating

Rotating proxy giúp phân phát tải đều qua nhiều IP và tránh bị rate limit. Tuy nhiên, một số trang yêu cầu duy trì cùng IP trong thời gian ngắn để xác thực phiên.

Cách cấu hình với thư viện requests-rotating

pip install requests-rotating
from requests_rotating import RotatingProxies

proxies_pool = [
    "http://user:pass@ip1:port",
    "http://user:pass@ip2:port",
    "http://user:pass@ip3:port",
]

rotator = RotatingProxies(proxies_pool)

for url in urls:
    proxy = rotator.get_proxy()
    response = requests.get(url, proxies={"https": proxy})

Rotating thủ công với round-robin

Nếu không muốn dùng thư viện bổ sung, có thể cài đặt đơn giản bằng iterator:

from itertools import cycle

proxy_pool = cycle([
    "http://user:pass@ip1:port",
    "http://user:pass@ip2:port",
])

for url in urls:
    proxy = next(proxy_pool)
    response = requests.get(url, proxies={"https": proxy})

Kiểm tra proxy trước khi dùng

Bước 1: Kiểm tra kết nối

import requests

def check_proxy(proxy_url):
    try:
        response = requests.get(
            "https://httpbin.org/ip",
            proxies={"https": proxy_url},
            timeout=10
        )
        return response.status_code == 200
    except Exception:
        return False

proxy_list = ["http://ip1:port", "http://ip2:port"]
valid_proxies = [p for p in proxy_list if check_proxy(p)]

Bước 2: Kiểm tra địa lý

import requests

def get_geo(proxy_url):
    response = requests.get(
        "https://ipinfo.io/json",
        proxies={"https": proxy_url},
        timeout=10
    )
    return response.json().get("country")

# Chỉ giữ lại proxy ở Việt Nam (VN)
vn_proxies = [p for p in valid_proxies if get_geo(p) == "VN"]

Bước 3: Theo dõi tốc độ

import time
import requests

def measure_latency(proxy_url):
    start = time.time()
    response = requests.get(
        "https://httpbin.org/delay/1",
        proxies={"https": proxy_url},
        timeout=5
    )
    return time.time() - start

fast_proxies = sorted(valid_proxies, key=measure_latency)[:10]

Xử lý lỗi phổ biến

Lỗi kết nối (Connection Error)

Thường xảy ra khi proxy không phản hồi. Cách xử lý:

  • Thử lại với proxy khác.
  • Kiểm tra timeout và tăng thời gian chờ.
  • Log lỗi để loại bỏ proxy không ổn.

Lỗi xác thực (407 Proxy Authentication Required)

Đảm bảo định dạng URL proxy đúng: protocol://username:password@ip:port. Một số proxy yêu cầu encoding URL.

Lỗi 429 Too Many Requests

Nếu proxy rotating vẫn nhận được 429, có hai nguyên nhân:

  1. IP đang bị chặn từ trước — cần bỏ khỏi pool.
  2. Tần suất gửi yêu cầu quá nhanh — thêm time.sleep() giữa các request.

Tối ưu chi phí và hiệu năng

Kết hợp sticky + rotating

Dùng sticky proxy cho các request cần xác thực (login, checkout), và rotating proxy cho các request độc lập (lấy sản phẩm, lấy giá).

Pool management

Duy trì một pool proxy lớn hơn nhu cầu thực tế để dự phòng:

  • Nếu cần 20 IP nhưng chỉ có 10, tăng dần lên 25 để tránh thiếu hụt.
  • Định kỳ kiểm tra và loại bỏ proxy không hoạt động.

Retry logic

import time
import requests

def fetch_with_retry(url, proxy, retries=3):
    for attempt in range(retries):
        try:
            response = requests.get(url, proxies={"https": proxy}, timeout=10)
            if response.status_code == 200:
                return response
        except Exception:
            pass
        time.sleep(2 ** attempt)  # Exponential backoff
    return None

Kết luận

Việc chọn proxy phù hợp cho scraper Python không chỉ là vấn đề kỹ thuật mà còn là chiến lược. Hãy bắt đầu với nhu cầu thực tế, kiểm tra kỹ lưỡng trước khi triễn khai, và luôn chuẩn bị fallback proxy để đảm bảo scraper chạy ổn định trong dài hạn.