Xử Lý Timeout Trong Python Requests: Hướng Dẫn Chi Tiết
Script scraping của bạn bị treo? Có thể bạn đang gặp vấn đề timeout. Bài này hướng dẫn cách xử lý timeout trong Python Requests đúng cách.
Timeout Là Gì?
Timeout là giới hạn thời gian chờ response từ server. Không có timeout = script có thể chờ mãi mãi.
Vấn Đề: Python Requests Không Có Default Timeout
Quan trọng: Mặc định, requests.get() không có timeout! Script có thể treo vô thời hạn nếu server không response.
# SAI - không có timeout, có thể treo mãi
response = requests.get('https://example.com')
# ĐÚNG - luôn set timeout
response = requests.get('https://example.com', timeout=5)
Connect Timeout vs Read Timeout
Có thể set 2 loại timeout riêng:
# timeout=(connect_timeout, read_timeout)
response = requests.get(url, timeout=(3, 10))
# 3 giây để connect
# 10 giây để đọc response
- Connect timeout: Thời gian mở kết nối. Nên ngắn (2-3s).
- Read timeout: Thời gian chờ data. Có thể dài hơn (10-15s).
Xử Lý Exception
import requests
from requests.exceptions import Timeout, ConnectTimeout, ReadTimeout
try:
response = requests.get(url, timeout=(3, 10))
except ConnectTimeout:
print("Không thể kết nối server")
except ReadTimeout:
print("Server không response kịp")
except Timeout:
print("Timeout chung")
Giá Trị Timeout Phổ Biến
| Use Case | Timeout |
|---|---|
| API nội bộ, nhanh | 2-3 giây |
| API public thông thường | 5 giây |
| Server chậm, xử lý nặng | 10-15 giây |
| Download file lớn | 30+ giây |
Retry Với Backoff
import time
import random
def request_with_retry(url, max_retries=3):
for i in range(max_retries):
try:
response = requests.get(url, timeout=5)
return response
except Timeout:
wait = (2 ** i) + random.uniform(0, 1)
print(f"Retry sau {wait:.1f}s...")
time.sleep(wait)
raise Exception("Max retries exceeded")
Dùng Session Với Default Timeout
from requests.adapters import HTTPAdapter
session = requests.Session()
session.mount('http://', HTTPAdapter(max_retries=3))
session.mount('https://', HTTPAdapter(max_retries=3))
# Mỗi request sẽ dùng config này
response = session.get(url, timeout=5)
Timeout Khi Dùng Proxy
proxies = {
'http': 'http://user:pass@proxy.vinaproxy.com:8080',
'https': 'http://user:pass@proxy.vinaproxy.com:8080'
}
# Tăng timeout khi dùng proxy (thêm latency)
response = requests.get(url, proxies=proxies, timeout=(5, 15))
VinaProxy Cho Scraping Ổn Định
- Residential proxy với uptime cao
- Latency thấp từ server Việt Nam
- Auto-retry nếu IP bị block
- Giá chỉ $0.5/GB
