Bảo vệ khỏi việc bị chặn khi gửi yêu cầu hàng loạt: kỹ thuật và công cụ
Việc chặn tài khoản và địa chỉ IP là vấn đề chính khi thu thập dữ liệu, tự động hóa và thực hiện các thao tác hàng loạt trên mạng xã hội. Các hệ thống chống bot hiện đại phân tích hàng chục thông số: từ tần suất yêu cầu đến dấu vân tay trình duyệt. Trong hướng dẫn này, chúng ta sẽ phân tích các cơ chế phát hiện tự động hóa và các cách thực tế để vượt qua chúng.
Cơ chế phát hiện tự động hóa
Các hệ thống bảo vệ hiện đại sử dụng phân tích đa tầng để phát hiện bot. Hiểu rõ những cơ chế này là rất quan trọng để chọn lựa chiến lược vượt qua phù hợp.
Các thông số phân tích chính
Danh tiếng IP: Các hệ thống chống bot kiểm tra lịch sử địa chỉ IP, thuộc về các trung tâm dữ liệu, có mặt trong danh sách đen hay không. IP từ các nhóm proxy nổi tiếng thường bị chặn nhiều hơn.
Tần suất yêu cầu (Request Rate): Con người không thể gửi 100 yêu cầu mỗi phút. Các hệ thống phân tích không chỉ tổng số lượng mà còn cả sự phân bố theo thời gian — các khoảng thời gian đều đặn giữa các yêu cầu sẽ phát hiện bot.
Mô hình hành vi: Chuỗi hành động, độ sâu cuộn trang, chuyển động chuột, thời gian trên trang. Bot chuyển tiếp liên kết ngay lập tức mà không có độ trễ sẽ dễ dàng bị phát hiện.
Dấu vân tay kỹ thuật: User-Agent, tiêu đề HTTP, thứ tự tiêu đề, dấu vân tay TLS, dấu vân tay Canvas/WebGL. Sự không khớp trong các thông số này là tín hiệu đỏ cho các hệ thống chống bot.
| Thông số | Nội dung phân tích | Rủi ro phát hiện |
|---|---|---|
| Địa chỉ IP | Danh tiếng, ASN, định vị địa lý | Cao |
| User-Agent | Phiên bản trình duyệt, HĐH, thiết bị | Trung bình |
| Dấu vân tay TLS | Tập hợp mã hóa, mở rộng | Cao |
| Dấu vân tay HTTP/2 | Thứ tự tiêu đề, cài đặt | Cao |
| Canvas/WebGL | Vẽ đồ họa | Trung bình |
| Hành vi | Nhấp chuột, cuộn trang, thời gian | Cao |
Giới hạn tốc độ và kiểm soát tần suất yêu cầu
Kiểm soát tốc độ gửi yêu cầu là hàng rào bảo vệ đầu tiên chống lại việc bị chặn. Ngay cả khi xoay vòng proxy, việc thu thập dữ liệu quá mức sẽ dẫn đến việc bị cấm.
Độ trễ động
Các khoảng thời gian cố định (ví dụ: đúng 2 giây giữa các yêu cầu) dễ dàng bị phát hiện. Sử dụng độ trễ ngẫu nhiên với phân phối chuẩn:
import time
import random
import numpy as np
def human_delay(min_delay=1.5, max_delay=4.0, mean=2.5, std=0.8):
"""
Tạo độ trễ với phân phối chuẩn
mô phỏng hành vi con người
"""
delay = np.random.normal(mean, std)
# Giới hạn khoảng
delay = max(min_delay, min(delay, max_delay))
# Thêm độ trễ vi mô để thực tế hơn
delay += random.uniform(0, 0.3)
time.sleep(delay)
# Sử dụng
for url in urls:
response = session.get(url)
human_delay(min_delay=2, max_delay=5, mean=3, std=1)
Giới hạn tốc độ thích ứng
Một cách tiếp cận tiên tiến hơn là điều chỉnh tốc độ dựa trên phản hồi từ máy chủ. Nếu nhận được mã 429 (Quá nhiều yêu cầu) hoặc 503, hãy tự động giảm tốc độ:
class AdaptiveRateLimiter:
def __init__(self, initial_delay=2.0):
self.current_delay = initial_delay
self.min_delay = 1.0
self.max_delay = 30.0
self.error_count = 0
def wait(self):
time.sleep(self.current_delay + random.uniform(0, 0.5))
def on_success(self):
# Tăng tốc độ dần dần khi có yêu cầu thành công
self.current_delay = max(
self.min_delay,
self.current_delay * 0.95
)
self.error_count = 0
def on_rate_limit(self):
# Giảm tốc độ ngay lập tức khi bị chặn
self.error_count += 1
self.current_delay = min(
self.max_delay,
self.current_delay * (1.5 + self.error_count * 0.5)
)
print(f"Đã đạt giới hạn tốc độ. Độ trễ mới: {self.current_delay:.2f}s")
# Áp dụng
limiter = AdaptiveRateLimiter(initial_delay=2.0)
for url in urls:
limiter.wait()
response = session.get(url)
if response.status_code == 429:
limiter.on_rate_limit()
time.sleep(60) # Tạm dừng trước khi thử lại
elif response.status_code == 200:
limiter.on_success()
else:
# Xử lý các lỗi khác
pass
Lời khuyên thực tế: Tốc độ tối ưu khác nhau cho các trang web khác nhau. Các nền tảng lớn (Google, Facebook) có thể chịu đựng 5-10 yêu cầu mỗi phút từ một IP. Các trang nhỏ có thể chặn ngay cả khi có 20-30 yêu cầu mỗi giờ. Luôn bắt đầu một cách thận trọng và từ từ tăng tải, theo dõi tỷ lệ lỗi.
Xoay vòng proxy và quản lý địa chỉ IP
Sử dụng một địa chỉ IP cho các yêu cầu hàng loạt đảm bảo sẽ bị chặn. Xoay vòng proxy phân phối tải và giảm rủi ro phát hiện.
Chiến lược xoay vòng
1. Xoay vòng theo yêu cầu: Thay đổi IP sau mỗi yêu cầu hoặc sau mỗi N yêu cầu. Phù hợp cho việc thu thập dữ liệu từ các công cụ tìm kiếm, nơi mà sự ẩn danh của mỗi yêu cầu là quan trọng.
2. Xoay vòng theo thời gian: Thay đổi IP mỗi 5-15 phút. Hiệu quả cho việc làm việc với mạng xã hội, nơi mà sự ổn định của phiên làm việc là quan trọng.
3. Phiên làm việc dính: Sử dụng một IP cho toàn bộ phiên làm việc của người dùng (đăng nhập, chuỗi hành động). Rất quan trọng cho các trang web có bảo vệ chống CSRF.
import requests
from itertools import cycle
class ProxyRotator:
def __init__(self, proxy_list, rotation_type='request', rotation_interval=10):
"""
rotation_type: 'request' (mỗi yêu cầu) hoặc 'time' (theo thời gian)
rotation_interval: số lượng yêu cầu hoặc giây
"""
self.proxies = cycle(proxy_list)
self.current_proxy = next(self.proxies)
self.rotation_type = rotation_type
self.rotation_interval = rotation_interval
self.request_count = 0
self.last_rotation = time.time()
def get_proxy(self):
if self.rotation_type == 'request':
self.request_count += 1
if self.request_count >= self.rotation_interval:
self.current_proxy = next(self.proxies)
self.request_count = 0
print(f"Đã xoay vòng đến: {self.current_proxy}")
elif self.rotation_type == 'time':
if time.time() - self.last_rotation >= self.rotation_interval:
self.current_proxy = next(self.proxies)
self.last_rotation = time.time()
print(f"Đã xoay vòng đến: {self.current_proxy}")
return {'http': self.current_proxy, 'https': self.current_proxy}
# Ví dụ sử dụng
proxy_list = [
'http://user:pass@proxy1.example.com:8000',
'http://user:pass@proxy2.example.com:8000',
'http://user:pass@proxy3.example.com:8000',
]
rotator = ProxyRotator(proxy_list, rotation_type='request', rotation_interval=5)
for url in urls:
proxies = rotator.get_proxy()
response = requests.get(url, proxies=proxies, timeout=10)
Lựa chọn loại proxy
| Loại proxy | Mức độ tin cậy | Tốc độ | Ứng dụng |
|---|---|---|---|
| Trung tâm dữ liệu | Thấp | Cao | Thu thập dữ liệu đơn giản, API |
| Proxy dân cư | Cao | Trung bình | Mạng xã hội, trang web bảo mật |
| Proxy di động | Rất cao | Trung bình | Instagram, TikTok, chống gian lận |
Đối với các hoạt động hàng loạt trên mạng xã hội và trên các nền tảng có bảo vệ nghiêm ngặt, hãy sử dụng proxy dân cư. Chúng trông giống như các kết nối gia đình thông thường và hiếm khi bị đưa vào danh sách đen. Trung tâm dữ liệu phù hợp cho các tài nguyên ít bảo mật hơn, nơi tốc độ là quan trọng.
Dấu vân tay trình duyệt và dấu vân tay TLS
Ngay cả khi xoay vòng IP, bạn có thể bị phát hiện qua các dấu vân tay kỹ thuật của trình duyệt và kết nối TLS. Những thông số này là duy nhất cho mỗi khách hàng và khó giả mạo.
Dấu vân tay TLS
Khi thiết lập kết nối HTTPS, khách hàng gửi ClientHello với tập hợp các mã hóa và mở rộng được hỗ trợ. Sự kết hợp này là duy nhất cho mỗi thư viện. Ví dụ, Python requests sử dụng OpenSSL, dấu vân tay của nó dễ dàng phân biệt với Chrome.
Vấn đề: Các thư viện tiêu chuẩn (requests, urllib, curl) có dấu vân tay khác với các trình duyệt thực tế. Các dịch vụ như Cloudflare, Akamai, DataDome tích cực sử dụng dấu vân tay TLS để chặn bot.
Giải pháp: Sử dụng các thư viện mô phỏng dấu vân tay TLS của trình duyệt. Đối với Python, có thể sử dụng curl_cffi, tls_client hoặc playwright/puppeteer để mô phỏng hoàn toàn trình duyệt.
# Cài đặt: pip install curl-cffi
from curl_cffi import requests
# Mô phỏng Chrome 110
response = requests.get(
'https://example.com',
impersonate="chrome110",
proxies={'https': 'http://proxy:port'}
)
# Thay thế: tls_client
import tls_client
session = tls_client.Session(
client_identifier="chrome_108",
random_tls_extension_order=True
)
response = session.get('https://example.com')
Dấu vân tay HTTP/2
Ngoài TLS, các hệ thống chống bot phân tích các thông số HTTP/2: thứ tự tiêu đề, cài đặt SETTINGS frame, ưu tiên luồng. Các thư viện tiêu chuẩn không tuân thủ thứ tự tiêu đề chính xác của Chrome hoặc Firefox.
# Thứ tự tiêu đề đúng cho Chrome
headers = {
':method': 'GET',
':authority': 'example.com',
':scheme': 'https',
':path': '/',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)...',
'accept': 'text/html,application/xhtml+xml...',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
}
Dấu vân tay Canvas và WebGL
Các trình duyệt vẽ đồ họa khác nhau tùy thuộc vào GPU, trình điều khiển và HĐH. Các trang web sử dụng điều này để tạo ra dấu vân tay thiết bị duy nhất. Khi sử dụng các trình duyệt headless (Selenium, Puppeteer), việc che giấu các dấu hiệu tự động hóa là rất quan trọng:
// Puppeteer: ẩn chế độ headless
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
headless: true,
args: [
'--disable-blink-features=AutomationControlled',
'--no-sandbox',
'--disable-setuid-sandbox',
`--proxy-server=${proxyUrl}`
]
});
const page = await browser.newPage();
// Ghi đè navigator.webdriver
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
});
Tiêu đề, cookies và quản lý phiên làm việc
Việc xử lý chính xác các tiêu đề HTTP và cookies là rất quan trọng để mô phỏng người dùng thực. Các lỗi trong các thông số này là nguyên nhân phổ biến gây ra việc bị chặn.
Các tiêu đề bắt buộc
Tập hợp tiêu đề tối thiểu để mô phỏng trình duyệt Chrome:
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Cache-Control': 'max-age=0',
}
session = requests.Session()
session.headers.update(headers)
Quản lý cookies
Nhiều trang web thiết lập tracking cookies khi lần đầu truy cập và kiểm tra sự tồn tại của chúng trong các yêu cầu tiếp theo. Việc thiếu cookies hoặc không khớp là dấu hiệu của bot.
import requests
import pickle
class SessionManager:
def __init__(self, session_file='session.pkl'):
self.session_file = session_file
self.session = requests.Session()
self.load_session()
def load_session(self):
"""Tải phiên đã lưu"""
try:
with open(self.session_file, 'rb') as f:
cookies = pickle.load(f)
self.session.cookies.update(cookies)
except FileNotFoundError:
pass
def save_session(self):
"""Lưu cookies để sử dụng lại"""
with open(self.session_file, 'wb') as f:
pickle.dump(self.session.cookies, f)
def request(self, url, **kwargs):
response = self.session.get(url, **kwargs)
self.save_session()
return response
# Sử dụng
manager = SessionManager('instagram_session.pkl')
response = manager.request('https://www.instagram.com/explore/')
Quan trọng: Khi xoay vòng proxy, đừng quên đặt lại cookies nếu chúng liên kết với một IP cụ thể. Sự không khớp giữa IP và cookies (ví dụ, cookies với định vị địa lý ở Mỹ và IP từ Đức) sẽ gây nghi ngờ.
Referer và Origin
Các tiêu đề Referer và Origin cho biết người dùng đến từ đâu. Việc thiếu hoặc giá trị không chính xác là tín hiệu đỏ.
# Thứ tự đúng: trang chính → danh mục → sản phẩm
session = requests.Session()
# Bước 1: truy cập trang chính
response = session.get('https://example.com/')
# Bước 2: chuyển đến danh mục
response = session.get(
'https://example.com/category/electronics',
headers={'Referer': 'https://example.com/'}
)
# Bước 3: xem sản phẩm
response = session.get(
'https://example.com/product/12345',
headers={'Referer': 'https://example.com/category/electronics'}
)
Mô phỏng hành vi con người
Các thông số kỹ thuật chỉ là một nửa của vấn đề. Các hệ thống chống bot hiện đại phân tích các mẫu hành vi: cách người dùng tương tác với trang, thời gian họ dành cho trang, cách di chuyển chuột.
Cuộn trang và di chuyển chuột
Khi sử dụng Selenium hoặc Puppeteer, hãy thêm các chuyển động chuột ngẫu nhiên và cuộn trang:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import random
import time
def human_like_mouse_move(driver):
"""Di chuyển chuột ngẫu nhiên trên trang"""
action = ActionChains(driver)
for _ in range(random.randint(3, 7)):
x = random.randint(0, 1000)
y = random.randint(0, 800)
action.move_by_offset(x, y)
action.pause(random.uniform(0.1, 0.3))
action.perform()
def human_like_scroll(driver):
"""Mô phỏng cuộn tự nhiên"""
total_height = driver.execute_script("return document.body.scrollHeight")
current_position = 0
while current_position < total_height:
# Bước cuộn ngẫu nhiên
scroll_step = random.randint(100, 400)
current_position += scroll_step
driver.execute_script(f"window.scrollTo(0, {current_position});")
# Tạm dừng với biến thể
time.sleep(random.uniform(0.5, 1.5))
# Đôi khi cuộn ngược lại một chút (như con người làm)
if random.random() < 0.2:
back_scroll = random.randint(50, 150)
current_position -= back_scroll
driver.execute_script(f"window.scrollTo(0, {current_position});")
time.sleep(random.uniform(0.3, 0.8))
# Sử dụng
driver = webdriver.Chrome()
driver.get('https://example.com')
human_like_mouse_move(driver)
time.sleep(random.uniform(2, 4))
human_like_scroll(driver)
Thời gian trên trang
Người dùng thực sự dành thời gian trên trang: đọc nội dung, xem hình ảnh. Bot chuyển tiếp liên kết ngay lập tức sẽ dễ dàng bị phát hiện.
def realistic_page_view(driver, url, min_time=5, max_time=15):
"""
Xem trang một cách thực tế với hoạt động
"""
driver.get(url)
# Độ trễ ban đầu (tải và "đọc")
time.sleep(random.uniform(2, 4))
# Cuộn trang
human_like_scroll(driver)
# Hoạt động bổ sung
total_time = random.uniform(min_time, max_time)
elapsed = 0
while elapsed < total_time:
action_choice = random.choice(['scroll', 'mouse_move', 'pause'])
if action_choice == 'scroll':
# Cuộn nhẹ lên/xuống
scroll_amount = random.randint(-200, 300)
driver.execute_script(f"window.scrollBy(0, {scroll_amount});")
pause = random.uniform(1, 3)
elif action_choice == 'mouse_move':
human_like_mouse_move(driver)
pause = random.uniform(0.5, 2)
else: # pause
pause = random.uniform(2, 5)
time.sleep(pause)
elapsed += pause
Mẫu điều hướng
Tránh các mẫu đáng ngờ: chuyển tiếp trực tiếp đến các trang sâu, bỏ qua trang chính, duyệt tất cả các phần tử mà không bỏ lỡ.
Thực hành tốt:
- Bắt đầu từ trang chính hoặc các phần phổ biến
- Sử dụng điều hướng nội bộ của trang web, không phải URL trực tiếp
- Đôi khi quay lại hoặc chuyển đến các phần khác
- Thay đổi độ sâu xem: không phải lúc nào cũng đến cuối
- Thêm "lỗi": chuyển tiếp đến các liên kết không tồn tại, quay lại
Vượt qua Cloudflare, DataDome và các biện pháp bảo vệ khác
Các hệ thống chống bot chuyên dụng yêu cầu một cách tiếp cận toàn diện. Chúng sử dụng các thử thách JavaScript, CAPTCHA, phân tích hành vi trong thời gian thực.
Cloudflare
Cloudflare sử dụng nhiều lớp bảo vệ: Kiểm tra tính toàn vẹn của trình duyệt, Thử thách JavaScript, CAPTCHA. Để vượt qua bảo vệ cơ bản, chỉ cần có dấu vân tay TLS chính xác và thực hiện JavaScript:
# Phương án 1: cloudscraper (giải quyết tự động các thử thách JS)
import cloudscraper
scraper = cloudscraper.create_scraper(
browser={
'browser': 'chrome',
'platform': 'windows',
'desktop': True
}
)
response = scraper.get('https://protected-site.com')
# Phương án 2: undetected-chromedriver (cho các trường hợp phức tạp)
import undetected_chromedriver as uc
options = uc.ChromeOptions()
options.add_argument('--proxy-server=http://proxy:port')
driver = uc.Chrome(options=options)
driver.get('https://protected-site.com')
# Chờ đợi vượt qua thử thách
time.sleep(5)
# Lấy cookies cho requests
cookies = driver.get_cookies()
session = requests.Session()
for cookie in cookies:
session.cookies.set(cookie['name'], cookie['value'])
DataDome
DataDome phân tích hành vi người dùng trong thời gian thực: chuyển động chuột, chữ ký bàn phím, thời gian. Để vượt qua, cần có một trình duyệt hoàn chỉnh với mô phỏng hoạt động:
from playwright.sync_api import sync_playwright
import random
def bypass_datadome(url, proxy=None):
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False, # DataDome phát hiện headless
proxy={'server': proxy} if proxy else None
)
context = browser.new_context(
viewport={'width': 1920, 'height': 1080},
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)...'
)
page = context.new_page()
# Tiêm mã để che giấu tự động hóa
page.add_init_script("""
Object.defineProperty(navigator, 'webdriver', {get: () => false});
window.chrome = {runtime: {}};
""")
page.goto(url)
# Mô phỏng hành vi con người
time.sleep(random.uniform(2, 4))
# Di chuyển chuột ngẫu nhiên
for _ in range(random.randint(5, 10)):
page.mouse.move(
random.randint(100, 1800),
random.randint(100, 1000)
)
time.sleep(random.uniform(0.1, 0.3))
# Cuộn trang
page.evaluate(f"window.scrollTo(0, {random.randint(300, 800)})")
time.sleep(random.uniform(1, 2))
content = page.content()
browser.close()
return content
CAPTCHA
Để giải quyết CAPTCHA tự động, hãy sử dụng các dịch vụ nhận diện (2captcha, Anti-Captcha) hoặc các chiến lược tránh né:
- Giảm tần suất yêu cầu xuống mức không gây ra CAPTCHA
- Sử dụng IP dân cư sạch với danh tiếng tốt
- Làm việc qua các tài khoản đã được xác thực (có ngưỡng CAPTCHA cao hơn)
- Phân phối tải theo thời gian (tránh giờ cao điểm)
Giám sát và xử lý việc bị chặn
Ngay cả với các thực hành tốt nhất, việc bị chặn là không thể tránh khỏi. Quan trọng là phát hiện nhanh chóng và xử lý đúng cách.
Các chỉ số bị chặn
| Tín hiệu | Mô tả | Hành động |
|---|---|---|
| HTTP 429 | Quá nhiều yêu cầu | Tăng độ trễ, thay đổi IP |
| HTTP 403 | Bị cấm (IP bị chặn) | Thay đổi proxy, kiểm tra fingerprint |
| CAPTCHA | Cần xác thực | Giải quyết hoặc giảm hoạt động |
| Phản hồi trống | Nội dung không tải được | Kiểm tra JavaScript, cookies |
| Chuyển hướng đến /blocked | Bị chặn rõ ràng | Thay đổi hoàn toàn chiến lược |
Hệ thống thử lại
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_session_with_retries():
"""
Phiên làm việc với các lần thử tự động và xử lý lỗi
"""
session = requests.Session()
retry_strategy = Retry(
total=5,
backoff_factor=2, # 2, 4, 8, 16, 32 giây
status_forcelist=[429, 500, 502, 503, 504],
method_whitelist=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session
def safe_request(url, session, max_attempts=3):
"""
Yêu cầu với xử lý việc bị chặn
"""
for attempt in range(max_attempts):
try:
response = session.get(url, timeout=15)
# Kiểm tra việc bị chặn
if response.status_code == 403:
print(f"IP bị chặn. Đang xoay vòng proxy...")
# Logic thay đổi proxy
continue
elif response.status_code == 429:
wait_time = int(response.headers.get('Retry-After', 60))
print(f"Đã đạt giới hạn tốc độ. Đợi {wait_time}s...")
time.sleep(wait_time)
continue
elif 'captcha' in response.text.lower():
print("Đã phát hiện CAPTCHA")
# Logic giải quyết CAPTCHA hoặc bỏ qua
return None
return response
except requests.exceptions.Timeout:
print(f"Hết thời gian ở lần thử {attempt + 1}")
time.sleep(5 * (attempt + 1))
except requests.exceptions.ProxyError:
print("Lỗi proxy. Đang xoay vòng...")
# Thay đổi proxy
continue
return None
Ghi log và phân tích
Theo dõi các chỉ số để tối ưu hóa chiến lược:
import logging
from collections import defaultdict
from datetime import datetime
class ScraperMetrics:
def __init__(self):
self.stats = {
'total_requests': 0,
'successful': 0,
'rate_limited': 0,
'blocked': 0,
'captcha': 0,
'errors': 0,
'proxy_failures': defaultdict(int)
}
def log_request(self, status, proxy=None):
self.stats['total_requests'] += 1
if status == 200:
self.stats['successful'] += 1
elif status == 429:
self.stats['rate_limited'] += 1
elif status == 403:
self.stats['blocked'] += 1
if proxy:
self.stats['proxy_failures'][proxy] += 1
def get_success_rate(self):
if self.stats['total_requests'] == 0:
return 0
return (self.stats['successful'] / self.stats['total_requests']) * 100
def print_report(self):
print(f"\n=== Báo cáo thu thập dữ liệu ===")
print(f"Tổng số yêu cầu: {self.stats['total_requests']}")
print(f"Tỷ lệ thành công: {self.get_success_rate():.2f}%")
print(f"Bị giới hạn tốc độ: {self.stats['rate_limited']}")
print(f"Bị chặn: {self.stats['blocked']}")
print(f"CAPTCHA: {self.stats['captcha']}")
if self.stats['proxy_failures']:
print(f"\nCác proxy gặp vấn đề:")
for proxy, count in sorted(
self.stats['proxy_failures'].items(),
key=lambda x: x[1],
reverse=True
)[:5]:
print(f" {proxy}: {count} lần thất bại")
# Sử dụng
metrics = ScraperMetrics()
for url in urls:
response = safe_request(url, session)
if response:
metrics.log_request(response.status_code, current_proxy)
metrics.print_report()
Các chỉ số tối ưu: Tỷ lệ thành công trên 95% — kết quả tuyệt vời. 80-95% — chấp nhận được, nhưng cần cải thiện. Dưới 80% — xem xét lại chiến lược: có thể là giới hạn tốc độ quá mức, proxy kém hoặc vấn đề với dấu vân tay.
Kết luận
Bảo vệ khỏi việc bị chặn khi gửi yêu cầu hàng loạt là một quá trình phức tạp, yêu cầu sự hiểu biết sâu sắc về các cơ chế phát hiện và các chiến lược vượt qua. Bằng cách áp dụng các kỹ thuật và công cụ đã đề cập trong bài viết này, bạn có thể giảm thiểu rủi ro và tối ưu hóa hiệu suất thu thập dữ liệu của mình.