Bạn đã cấu hình trình thu thập dữ liệu, kết nối proxy, nhưng API vẫn trả về lỗi 429 "Quá nhiều yêu cầu" hoặc chặn quyền truy cập? Vấn đề không nằm ở proxy mà ở chiến lược sử dụng không đúng. Rate limiting — là một cơ chế bảo vệ của API, hạn chế số lượng yêu cầu từ một địa chỉ IP trong một khoảng thời gian nhất định. Trong bài viết này, chúng ta sẽ phân tích lý do tại sao xảy ra chặn khi làm việc qua proxy và cách cấu hình hệ thống đúng cách để vượt qua giới hạn.
Rate limiting API là gì và nó hoạt động như thế nào
Rate limiting (giới hạn tần suất yêu cầu) — là cơ chế bảo vệ API khỏi quá tải và lạm dụng. Dịch vụ thiết lập giới hạn cho số lượng yêu cầu có thể thực hiện từ một nguồn trong một khoảng thời gian nhất định. Ví dụ, các API phổ biến sử dụng những giới hạn như:
- Twitter API: 300 yêu cầu trong 15 phút cho quyền truy cập tiêu chuẩn
- Instagram Graph API: 200 yêu cầu mỗi giờ cho ứng dụng
- Google Maps API: phụ thuộc vào gói dịch vụ, thường là 100-1000 yêu cầu mỗi ngày
- Wildberries API: giới hạn không chính thức khoảng 60 yêu cầu mỗi phút từ một IP
- Avito API: 10 yêu cầu mỗi giây để thu thập thông tin quảng cáo
Có một số phương pháp xác định nguồn yêu cầu mà rate limiting được áp dụng:
Địa chỉ IP: phương pháp phổ biến nhất. API đếm số lượng yêu cầu từ một IP cụ thể trong một khoảng thời gian.
Khóa API: nếu bạn sử dụng xác thực qua khóa, giới hạn sẽ được gán cho nó bất kể IP.
User-Agent và fingerprint: một số API phân tích tiêu đề trình duyệt và tạo ra dấu vân tay số cho khách hàng.
Phiên (cookies): giới hạn có thể được gán cho phiên người dùng thông qua cookies.
Khi vượt quá giới hạn, API trả về trạng thái HTTP 429 "Quá nhiều yêu cầu" và tiêu đề Retry-After, chỉ ra thời gian đến khi giới hạn được đặt lại. Một số dịch vụ sử dụng "cửa sổ trượt" (rolling window), nơi giới hạn được cập nhật dần dần, trong khi những dịch vụ khác sử dụng cửa sổ cố định, được đặt lại vào một thời điểm nhất định.
Tại sao proxy không tự động cứu thoát khỏi rate limiting
Nhiều nhà phát triển nhầm tưởng rằng chỉ cần kết nối proxy — và có thể gửi một số lượng yêu cầu không giới hạn. Trên thực tế, các vấn đề như sau xảy ra:
Sử dụng một proxy cho tất cả các yêu cầu
Nếu kịch bản của bạn sử dụng cùng một địa chỉ IP proxy cho tất cả các yêu cầu, API sẽ coi đây là người dùng bình thường và áp dụng các giới hạn tiêu chuẩn. Ví dụ, bạn đã cấu hình trình thu thập giá từ Wildberries qua một proxy cư trú. Trình thu thập thực hiện 100 yêu cầu mỗi phút, nhưng giới hạn là 60 yêu cầu. Kết quả: địa chỉ IP bị chặn trong 10-30 phút.
Xoay vòng IP chậm
Một số người sử dụng một nhóm từ 5-10 proxy và chuyển đổi giữa chúng một cách tuần tự. Vấn đề là mỗi IP vẫn đạt giới hạn nhanh hơn so với việc xoay vòng hoàn toàn. Giả sử bạn có 10 proxy và giới hạn là 100 yêu cầu mỗi giờ cho mỗi IP. Nếu bạn thực hiện 1000 yêu cầu mỗi giờ, mỗi proxy sẽ nhận 100 yêu cầu — đúng ở giới hạn. Bất kỳ sự phân phối không đồng đều nào cũng sẽ dẫn đến việc bị chặn.
Bỏ qua các yếu tố xác định khác
Ngay cả khi có xoay vòng IP hoàn hảo, bạn vẫn có thể bị chặn nếu:
- Tất cả các yêu cầu đều đến từ cùng một User-Agent (ví dụ,
python-requests/2.28.0) - Sử dụng một khóa API cho tất cả các yêu cầu
- Các yêu cầu đến với tần suất hoàn hảo (mỗi 0.5 giây) — điều này trông giống như bot
- Các địa chỉ IP của proxy nằm trong cùng một subnet (ví dụ, tất cả trong phạm vi 192.168.1.x)
Danh tiếng của các địa chỉ IP
Proxy từ trung tâm dữ liệu thường bị đưa vào danh sách đen, vì các IP của chúng được hàng trăm người dùng khác sử dụng để thu thập dữ liệu. API có thể áp dụng các giới hạn nghiêm ngặt hơn cho những địa chỉ này hoặc chặn chúng ngay lập tức. Ví dụ, Instagram và Facebook thường xuyên cấm các trung tâm dữ liệu, ngay cả khi bạn không vượt quá các giới hạn chính thức.
Chiến lược xoay vòng IP để vượt qua giới hạn
Xoay vòng proxy đúng cách là chìa khóa để vượt qua rate limiting. Hãy xem xét các chiến lược hiệu quả tùy thuộc vào nhiệm vụ.
Xoay vòng sau mỗi yêu cầu
Chiến lược mạnh mẽ nhất: mỗi yêu cầu đi qua một IP mới. Phù hợp cho các nhiệm vụ có giới hạn rất nghiêm ngặt (1-5 yêu cầu từ IP) hoặc khi cần phân bổ tải tối đa. Để làm điều này, sử dụng proxy cư trú với xoay vòng tự động — chúng cung cấp một nhóm hàng triệu IP, và mỗi yêu cầu tự động nhận một địa chỉ mới.
Ví dụ sử dụng: thu thập dữ liệu Instagram qua API không chính thức, nơi giới hạn là 5 yêu cầu mỗi phút từ một IP. Với việc xoay vòng sau mỗi yêu cầu, bạn có thể thực hiện 300 yêu cầu mỗi phút qua 300 IP khác nhau.
Ưu điểm: bảo vệ tối đa khỏi rate limiting, mỗi IP được sử dụng tối thiểu.
Nhược điểm: chi phí cao (proxy cư trú đắt hơn), có thể có độ trễ khi chuyển đổi IP, khó duy trì các phiên.
Xoay vòng theo thời gian (sticky sessions)
Địa chỉ IP được sử dụng trong một khoảng thời gian nhất định (5-30 phút), sau đó sẽ thay đổi thành một cái mới. Chiến lược này phù hợp cho các API yêu cầu lưu giữ phiên, hoặc khi cần thực hiện một số yêu cầu liên quan từ một "người dùng".
Tính toán thời gian xoay vòng tối ưu: nếu giới hạn API là 100 yêu cầu mỗi giờ, và bạn dự định thực hiện 50 yêu cầu qua một IP, hãy sử dụng sticky session trong 30 phút. Trong khoảng thời gian này, bạn sẽ thực hiện 25 yêu cầu (với tải đều), điều này thấp hơn gấp đôi giới hạn.
Xoay vòng theo nhóm với theo dõi giới hạn
Chiến lược nâng cao: kịch bản của bạn theo dõi số lượng yêu cầu từ mỗi IP và tự động chuyển sang cái mới khi gần đạt giới hạn. Ví dụ, bạn có một nhóm 20 proxy, giới hạn API là 100 yêu cầu mỗi giờ. Kịch bản theo dõi bộ đếm cho mỗi IP và chuyển sang cái tiếp theo khi đạt 90 yêu cầu.
Chiến lược này yêu cầu lập trình logic, nhưng mang lại hiệu quả tối đa: bạn sử dụng mỗi proxy với công suất tối đa mà không vượt quá giới hạn.
Xoay vòng địa lý
Một số API áp dụng các giới hạn khác nhau tùy thuộc vào khu vực. Ví dụ, dịch vụ có thể hạn chế các yêu cầu từ Hoa Kỳ nghiêm ngặt hơn so với từ Châu Âu. Trong những trường hợp như vậy, hãy sử dụng proxy từ các quốc gia khác nhau và phân bổ tải giữa chúng.
| Chiến lược xoay vòng | Khi nào sử dụng | Loại proxy |
|---|---|---|
| Sau mỗi yêu cầu | Giới hạn nghiêm ngặt (1-10 yêu cầu/IP), thu thập dữ liệu mạng xã hội | Proxy cư trú với xoay vòng tự động |
| Theo thời gian (5-30 phút) | Cần phiên, giới hạn trung bình (50-200 yêu cầu/giờ) | Proxy cư trú sticky hoặc di động |
| Theo nhóm với theo dõi giới hạn | Khối lượng lớn thu thập dữ liệu, giới hạn API đã biết | Bất kỳ loại nào với nhóm 10+ IP |
| Địa lý | Giới hạn theo khu vực, thu thập nội dung địa phương | Proxy cư trú từ các quốc gia khác nhau |
Cấu hình độ trễ giữa các yêu cầu
Ngay cả với xoay vòng IP hoàn hảo, việc cấu hình đúng độ trễ giữa các yêu cầu là rất quan trọng. Các yêu cầu quá nhanh trông giống như một cuộc tấn công, ngay cả khi chúng đến từ các IP khác nhau.
Tính toán độ trễ tối thiểu
Công thức: độ trễ = (cửa sổ thời gian tính bằng giây / giới hạn yêu cầu) × hệ số an toàn
Ví dụ: API cho phép 100 yêu cầu mỗi giờ (3600 giây). Độ trễ tối thiểu = 3600 / 100 = 36 giây. Thêm hệ số an toàn 1.2: 36 × 1.2 = 43 giây giữa các yêu cầu từ một IP.
Nếu bạn sử dụng 10 proxy với xoay vòng, bạn có thể thực hiện các yêu cầu mỗi 4.3 giây (43 / 10), không vượt quá giới hạn trên bất kỳ IP nào.
Độ trễ ngẫu nhiên (jitter)
Thay vì độ trễ cố định 5 giây, hãy sử dụng các khoảng thời gian ngẫu nhiên, chẳng hạn từ 3 đến 7 giây. Điều này làm cho lưu lượng của bạn giống như hành động của người dùng thực. Nhiều hệ thống bảo vệ bot phân tích các mẫu: nếu các yêu cầu đến đúng mỗi 5.0 giây, điều này là đáng ngờ.
Độ trễ theo cấp số nhân khi có lỗi
Khi nhận được lỗi 429, đừng tiếp tục gửi yêu cầu ngay lập tức. Sử dụng độ trễ theo cấp số nhân: lần thử đầu tiên sau 1 giây, lần thứ hai sau 2 giây, lần thứ ba sau 4 giây, lần thứ tư sau 8 giây và cứ tiếp tục như vậy. Đây là một thực hành tiêu chuẩn mà API mong đợi từ khách hàng.
Mẹo: Kiểm tra tiêu đề Retry-After trong phản hồi của API. Nó chỉ ra thời gian chính xác khi có thể lặp lại yêu cầu. Sử dụng giá trị này thay vì độ trễ tùy ý.
Loại proxy nào nên chọn để làm việc với API
Việc lựa chọn loại proxy ảnh hưởng rất lớn đến thành công trong việc vượt qua rate limiting. Hãy phân tích ưu và nhược điểm của từng tùy chọn để làm việc với API.
Proxy cư trú
Proxy cư trú sử dụng các địa chỉ IP của người dùng thực, được cung cấp bởi các nhà cung cấp dịch vụ Internet. Đối với API, điều này trông giống như Internet gia đình bình thường.
Ưu điểm cho API:
- Độ tin cậy cao: API hiếm khi cấm các IP gia đình
- Nhóm lớn: hàng triệu IP để xoay vòng
- Đa dạng địa lý: IP từ nhiều thành phố và quốc gia khác nhau
- Phù hợp cho mạng xã hội và API nghiêm ngặt (Instagram, Facebook, TikTok)
Nhược điểm:
- Chi phí cao: thanh toán thường theo lưu lượng (từ $5-15 cho 1 GB)
- Tốc độ biến đổi: phụ thuộc vào Internet của người dùng cuối
- Không ổn định: IP có thể ngắt kết nối bất kỳ lúc nào
Khi nào sử dụng: thu thập dữ liệu Instagram, Facebook, TikTok, làm việc với API của các chợ điện tử (Wildberries, Ozon), bất kỳ nhiệm vụ nào mà danh tiếng của IP là rất quan trọng.
Proxy di động
Proxy di động sử dụng các IP của các nhà mạng di động (4G/5G). Một IP thường được sử dụng bởi hàng ngàn người dùng thực cùng lúc, vì vậy API rất hiếm khi chặn chúng.
Ưu điểm cho API:
- Độ tin cậy tối đa: API không thể cấm IP của các nhà mạng di động
- Hoàn hảo cho các ứng dụng di động và API (Instagram, TikTok, Snapchat)
- Tự động thay đổi IP khi kết nối lại (chế độ máy bay)
- Một IP có thể thực hiện nhiều yêu cầu hơn mà không bị cấm
Nhược điểm:
- Chi phí rất cao: từ $50-150 cho một IP mỗi tháng
- Nhóm nhỏ: khó để có hàng trăm IP di động
- Tốc độ biến đổi: phụ thuộc vào chất lượng tín hiệu di động
Khi nào sử dụng: làm việc với các API di động, thu thập dữ liệu Instagram/TikTok với khối lượng lớn, khi cần bảo vệ tối đa khỏi việc bị cấm.
Proxy từ trung tâm dữ liệu
Proxy từ trung tâm dữ liệu — là các địa chỉ IP của các máy chủ đặt tại các trung tâm dữ liệu. Chúng không liên kết với người dùng thực.
Ưu điểm cho API:
- Chi phí thấp: từ $1-5 cho mỗi IP mỗi tháng
- Tốc độ cao: băng thông 1-10 Gbps
- Ổn định: IP không ngắt kết nối ngẫu nhiên
- Nhóm lớn: dễ dàng có hàng trăm IP
Nhược điểm:
- Độ tin cậy thấp: nhiều API chặn các trung tâm dữ liệu
- IP thường nằm trong danh sách đen do các người dùng khác
- Không phù hợp cho mạng xã hội và các dịch vụ nghiêm ngặt
Khi nào sử dụng: thu thập dữ liệu từ các API công khai không có bảo vệ nghiêm ngặt (thời tiết, tỷ giá hối đoái, tin tức), làm việc với các API riêng, thử nghiệm và phát triển.
| Tiêu chí | Proxy cư trú | Proxy di động | Proxy trung tâm dữ liệu |
|---|---|---|---|
| Độ tin cậy của API | Cao | Tối đa | Thấp |
| Kích thước nhóm | Hàng triệu IP | Hàng trăm IP | Hàng ngàn IP |
| Tốc độ | Trung bình (10-50 Mbit/s) | Trung bình (5-100 Mbit/s) | Cao (100+ Mbit/s) |
| Chi phí | $5-15/GB | $50-150/IP/tháng | $1-5/IP/tháng |
| Cho mạng xã hội | ✅ Tuyệt vời | ✅ Hoàn hảo | ❌ Không phù hợp |
| Cho API công khai | ✅ Tốt | ✅ Tốt (đắt) | ✅ Tuyệt vời |
Triển khai thực tế: ví dụ mã trên Python
Hãy xem xét các ví dụ cụ thể về việc vượt qua rate limiting bằng cách sử dụng proxy. Tất cả các ví dụ đều bằng Python với thư viện requests.
Xoay vòng đơn giản từ nhóm proxy
Triển khai cơ bản với xoay vòng theo chu kỳ IP từ danh sách:
import requests
import time
from itertools import cycle
# Danh sách proxy (định dạng: protocol://user:pass@host:port)
PROXY_LIST = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080',
]
# Tạo một bộ lặp theo chu kỳ
proxy_pool = cycle(PROXY_LIST)
def make_request(url):
proxy = next(proxy_pool) # Lấy proxy tiếp theo từ nhóm
proxies = {
'http': proxy,
'https': proxy
}
try:
response = requests.get(url, proxies=proxies, timeout=10)
return response
except requests.exceptions.RequestException as e:
print(f"Lỗi với proxy {proxy}: {e}")
return None
# Ví dụ sử dụng
for i in range(10):
response = make_request('https://api.example.com/data')
if response and response.status_code == 200:
print(f"Yêu cầu {i+1}: thành công")
time.sleep(2) # Độ trễ giữa các yêu cầu
Xoay vòng với theo dõi giới hạn
Phiên bản nâng cao hơn, theo dõi số lượng yêu cầu cho mỗi proxy và chuyển đổi khi gần đạt giới hạn:
import requests
import time
from collections import defaultdict
class ProxyRotator:
def __init__(self, proxy_list, max_requests_per_ip=90, time_window=3600):
self.proxy_list = proxy_list
self.max_requests = max_requests_per_ip # Giới hạn yêu cầu trên IP
self.time_window = time_window # Cửa sổ thời gian tính bằng giây
self.request_counts = defaultdict(list) # Lịch sử yêu cầu cho mỗi IP
self.current_index = 0
def get_proxy(self):
"""Trả về proxy với số lượng yêu cầu ít nhất"""
current_time = time.time()
# Xóa các bản ghi cũ vượt quá cửa sổ thời gian
for proxy in self.request_counts:
self.request_counts[proxy] = [
t for t in self.request_counts[proxy]
if current_time - t < self.time_window
]
# Tìm proxy với số lượng yêu cầu ít nhất
available_proxies = []
for proxy in self.proxy_list:
count = len(self.request_counts[proxy])
if count < self.max_requests:
available_proxies.append((proxy, count))
if not available_proxies:
# Nếu tất cả proxy đã đạt giới hạn, chờ đợi
oldest_request = min(
min(times) for times in self.request_counts.values() if times
)
wait_time = self.time_window - (current_time - oldest_request) + 1
print(f"Tất cả proxy đã đạt giới hạn. Chờ {wait_time:.0f} giây...")
time.sleep(wait_time)
return self.get_proxy()
# Chọn proxy với số lượng yêu cầu ít nhất
proxy = min(available_proxies, key=lambda x: x[1])[0]
self.request_counts[proxy].append(current_time)
return proxy
def make_request(self, url, **kwargs):
proxy = self.get_proxy()
proxies = {'http': proxy, 'https': proxy}
try:
response = requests.get(url, proxies=proxies, timeout=10, **kwargs)
return response
except requests.exceptions.RequestException as e:
print(f"Lỗi với proxy {proxy}: {e}")
return None
# Ví dụ sử dụng
PROXY_LIST = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
]
rotator = ProxyRotator(PROXY_LIST, max_requests_per_ip=100, time_window=3600)
for i in range(500): # Thực hiện 500 yêu cầu
response = rotator.make_request('https://api.example.com/data')
if response and response.status_code == 200:
print(f"Yêu cầu {i+1}: thành công")
time.sleep(1) # Độ trễ tối thiểu
Xử lý lỗi 429 với độ trễ theo cấp số nhân
Xử lý đúng phản hồi "Quá nhiều yêu cầu" với tiêu đề Retry-After:
import requests
import time
def make_request_with_retry(url, proxies, max_retries=5):
"""Thực hiện yêu cầu với các lần thử tự động khi có lỗi 429"""
for attempt in range(max_retries):
try:
response = requests.get(url, proxies=proxies, timeout=10)
if response.status_code == 200:
return response
elif response.status_code == 429:
# Kiểm tra tiêu đề Retry-After
retry_after = response.headers.get('Retry-After')
if retry_after:
wait_time = int(retry_after)
print(f"Giới hạn tần suất. Chờ {wait_time} giây (từ Retry-After)")
else:
# Độ trễ theo cấp số nhân: 2^attempt giây
wait_time = 2 ** attempt
print(f"Giới hạn tần suất. Cố gắng {attempt+1}, chờ {wait_time} giây")
time.sleep(wait_time)
continue
else:
print(f"Lỗi HTTP {response.status_code}")
return None
except requests.exceptions.RequestException as e:
print(f"Lỗi kết nối: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
return None
print(f>Vượt quá số lần thử ({max_retries})")
return None
# Ví dụ sử dụng
proxies = {
'http': 'http://user:pass@proxy.example.com:8080',
'https': 'http://user:pass@proxy.example.com:8080'
}
response = make_request_with_retry('https://api.example.com/data', proxies)
if response:
print("Dữ liệu đã nhận:", response.json())
Sử dụng proxy cư trú với xoay vòng tự động
Nhiều nhà cung cấp proxy cư trú cung cấp một endpoint duy nhất, tự động thay đổi IP cho mỗi yêu cầu. Ví dụ cấu hình:
import requests
import random
import time
# Proxy cư trú với xoay vòng tự động
# Định dạng: protocol://username:password@gateway:port
ROTATING_PROXY = 'http://customer-USER:PASS@proxy.provider.com:12321'
def make_request_rotating(url):
"""Yêu cầu qua proxy xoay vòng (IP mới mỗi lần)"""
proxies = {
'http': ROTATING_PROXY,
'https': ROTATING_PROXY
}
# Thêm User-Agent ngẫu nhiên để tăng tính ẩn danh
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
]
headers = {
'User-Agent': random.choice(user_agents)
}
try:
response = requests.get(url, proxies=proxies, headers=headers, timeout=15)
return response
except requests.exceptions.RequestException as e:
print(f"Lỗi: {e}")
return None
# Thực hiện 100 yêu cầu qua các IP khác nhau
for i in range(100):
response = make_request_rotating('https://api.example.com/data')
if response and response.status_code == 200:
print(f"Yêu cầu {i+1}: thành công, IP đã thay đổi")
# Độ trễ ngẫu nhiên 1-3 giây
time.sleep(random.uniform(1, 3))
Giám sát giới hạn và xử lý lỗi
Làm việc hiệu quả với API yêu cầu giám sát liên tục các giới hạn và xử lý lỗi đúng cách. Dưới đây là các thực hành chính:
Phân tích tiêu đề phản hồi
Nhiều API trả về thông tin về giới hạn trong tiêu đề phản hồi. Các tiêu đề tiêu chuẩn:
X-RateLimit-Limit— số lượng yêu cầu tối đa trong cửa sổX-RateLimit-Remaining— số yêu cầu còn lạiX-RateLimit-Reset— thời gian đặt lại giới hạn (timestamp Unix)Retry-After— sau bao lâu có thể lặp lại yêu cầu
Ví dụ đọc các tiêu đề này:
response = requests.get(url, proxies=proxies)
# Kiểm tra các tiêu đề giới hạn
limit = response.headers.get('X-RateLimit-Limit')
remaining = response.headers.get('X-RateLimit-Remaining')
reset_time = response.headers.get('X-RateLimit-Reset')
if remaining:
remaining = int(remaining)
if remaining < 10:
print(f"Cảnh báo! Chỉ còn {remaining} yêu cầu")
if reset_time:
import datetime
reset_dt = datetime.datetime.fromtimestamp(int(reset_time))
print(f"Giới hạn sẽ được đặt lại vào {reset_dt}")
Ghi chép và thống kê
Hãy giữ một thống kê chi tiết về các yêu cầu cho mỗi proxy. Điều này sẽ giúp phát hiện các IP gặp vấn đề và tối ưu hóa việc xoay vòng:
import json
from datetime import datetime
class RequestLogger:
def __init__(self):
self.stats = {}
def log_request(self, proxy, status_code, response_time):
if proxy not in self.stats:
self.stats[proxy] = {
'total': 0,
'success': 0,
'rate_limited': 0,
'errors': 0,
'avg_response_time': 0
}
self.stats[proxy]['total'] += 1
if status_code == 200:
self.stats[proxy]['success'] += 1
elif status_code == 429:
self.stats[proxy]['rate_limited'] += 1
else:
self.stats[proxy]['errors'] += 1
# Cập nhật thời gian phản hồi trung bình
current_avg = self.stats[proxy]['avg_response_time']
total = self.stats[proxy]['total']
self.stats[proxy]['avg_response_time'] = (
(current_avg * (total - 1) + response_time) / total
)
def print_stats(self):
print("\n=== Thống kê proxy ===")
for proxy, data in self.stats.items():
success_rate = (data['success'] / data['total'] * 100) if data['total'] > 0 else 0
print(f"\nProxy: {proxy}")
print(f" Tổng số yêu cầu: {data['total']}")
print(f" Thành công: {data['success']} ({success_rate:.1f}%)")
print(f" Rate limited: {data['rate_limited']}")
print(f" Lỗi: {data['errors']}")
print(f" Thời gian phản hồi trung bình: {data['avg_response_time']:.2f}s")
# Sử dụng
logger = RequestLogger()
start_time = time.time()
response = requests.get(url, proxies=proxies)
response_time = time.time() - start_time
logger.log_request(proxy, response.status_code, response_time)
logger.print_stats()
Tự động chuyển đổi chiến lược
Nếu bạn liên tục nhận được lỗi 429, hãy tự động làm chậm các yêu cầu hoặc tăng nhóm proxy:
class AdaptiveRateLimiter:
def __init__(self, initial_delay=1.0):
self.delay = initial_delay
self.consecutive_429 = 0
def on_success(self):
"""Yêu cầu thành công - có thể tăng tốc một chút"""
self.consecutive_429 = 0
self.delay = max(0.5, self.delay * 0.95) # Giảm độ trễ 5%
def on_rate_limit(self):
"""Nhận được 429 - cần làm chậm lại"""
self.consecutive_429 += 1
self.delay *= 1.5 # Tăng độ trễ gấp 1.5 lần
if self.consecutive_429 > 5:
print("CẢNH BÁO: Quá nhiều lỗi 429. Kiểm tra cấu hình!")
def wait(self):
"""Chờ trước khi thực hiện yêu cầu tiếp theo"""
time.sleep(self.delay)
return self.delay
# Sử dụng
limiter = AdaptiveRateLimiter(initial_delay=2.0)
for i in range(1000):
response = make_request(url)
if response.status_code == 200:
limiter.on_success()
elif response.status_code == 429:
limiter.on_rate_limit()
delay = limiter.wait()
print(f"Yêu cầu {i+1}, độ trễ: {delay:.2f}s")
Xử lý captcha và các chặn khác
Một số API khi vượt quá giới hạn hiển thị captcha thay vì chặn trực tiếp. Các dấu hiệu:
- Mã trạng thái 403 với nội dung phản hồi chứa "captcha" hoặc "recaptcha"
- Chuyển hướng đến trang có captcha (mã trạng thái 302)
- Các tiêu đề đặc biệt như
X-Captcha-Required: true
Trong những trường hợp như vậy, bạn cần:
- Ngừng ngay việc sử dụng IP này
- Chuyển sang một proxy khác từ nhóm
- Tăng độ trễ giữa các yêu cầu
- Thêm nhiều sự đa dạng vào User-Agent và các tiêu đề khác
Quan trọng: Nếu bạn thường xuyên gặp captcha khi sử dụng proxy cư trú, vấn đề có thể nằm ở mẫu hành vi (các tiêu đề giống nhau, yêu cầu quá nhanh), chứ không phải ở các địa chỉ IP.
Kết luận
Vượt qua rate limiting API khi sử dụng proxy không chỉ là một cấu hình kỹ thuật, mà là một chiến lược toàn diện, bao gồm việc lựa chọn đúng loại proxy, cấu hình xoay vòng IP, quản lý độ trễ và giám sát giới hạn. Các kết luận chính từ bài viết:
- Proxy tự nó không giải quyết vấn đề rate limiting — cần có chiến lược xoay vòng đúng đắn
- Đối với mạng xã hội và API nghiêm ngặt, hãy sử dụng proxy cư trú hoặc di động, cho các API công khai có thể sử dụng trung tâm dữ liệu
- Tính toán kích thước nhóm proxy dựa trên giới hạn API và tốc độ thu thập dữ liệu mong muốn
- Luôn kiểm tra và điều chỉnh chiến lược của bạn dựa trên phản hồi từ API