Прокси-чекер на Python — это программа, которая автоматизирует проверку работоспособности, скорости, типа и уровня анонимности списка прокси-серверов путем отправки тестовых запросов через каждый из них.
Что такое прокси-чекер и зачем он нужен
Прокси-чекер — это инструмент для валидации прокси-серверов. Он отправляет HTTP-запросы через заданный прокси на целевой URL, анализирует ответ и определяет статус прокси: активен ли он, какова его скорость, какой протокол поддерживает и насколько анонимен. Прокси-чекеры необходимы для поддержания актуального списка работоспособных прокси, особенно при работе с большими объемами или динамически меняющимися пулами прокси, например, в веб-скрейпинге, тестировании безопасности или управлении доступом.
Базовый прокси-чекер для HTTP/S
Основная функция прокси-чекера — выполнить HTTP-запрос через прокси и получить ответ. Для этого в Python используется библиотека requests.
Установка requests
pip install requests
Проверка HTTP/S прокси
Для проверки прокси необходимо указать его в параметре proxies при выполнении запроса.
import requests
import time
def check_http_proxy(proxy_url, target_url="http://httpbin.org/ip", timeout=5):
"""
Проверяет работоспособность HTTP/HTTPS прокси.
Args:
proxy_url (str): URL прокси (например, "http://ip:port" или "https://ip:port").
target_url (str): Целевой URL для проверки.
timeout (int): Таймаут в секундах для запроса.
Returns:
dict: Словарь с результатами проверки (статус, время ответа, IP).
"""
proxies = {
"http": proxy_url,
"https": proxy_url,
}
start_time = time.time()
try:
response = requests.get(target_url, proxies=proxies, timeout=timeout)
end_time = time.time()
response.raise_for_status() # Вызывает исключение для кодов ошибок HTTP
try:
# httpbin.org/ip возвращает JSON с IP-адресом, который видит сервер
data = response.json()
origin_ip = data.get('origin', 'N/A')
except requests.exceptions.JSONDecodeError:
origin_ip = "JSON Decode Error"
return {
"proxy": proxy_url,
"status": "рабочий",
"response_time": round((end_time - start_time) * 1000, 2), # мс
"protocol": "HTTP/HTTPS",
"origin_ip": origin_ip
}
except requests.exceptions.ConnectionError:
return {"proxy": proxy_url, "status": "отказ соединения", "response_time": None, "protocol": None, "origin_ip": None}
except requests.exceptions.Timeout:
return {"proxy": proxy_url, "status": "таймаут", "response_time": None, "protocol": None, "origin_ip": None}
except requests.exceptions.RequestException as e:
return {"proxy": proxy_url, "status": f"ошибка: {e}", "response_time": None, "protocol": None, "origin_ip": None}
# Пример использования:
# proxy_to_check = "http://192.168.1.1:8888" # Замените на реальный прокси
# result = check_http_proxy(proxy_to_check)
# print(result)
Определение типа прокси (SOCKS4/SOCKS5)
Библиотека requests по умолчанию не поддерживает SOCKS-прокси. Для работы с SOCKS необходимо установить дополнительную библиотеку PySocks и активировать ее интеграцию с requests.
Установка PySocks
pip install PySocks requests[socks]
Проверка SOCKS прокси
После установки PySocks, requests автоматически сможет использовать socks5:// и socks4:// схемы в параметре proxies.
import requests
import time
def check_socks_proxy(proxy_url, target_url="http://httpbin.org/ip", timeout=5):
"""
Проверяет работоспособность SOCKS4/SOCKS5 прокси.
Args:
proxy_url (str): URL SOCKS прокси (например, "socks5://ip:port" или "socks4://ip:port").
target_url (str): Целевой URL для проверки.
timeout (int): Таймаут в секундах для запроса.
Returns:
dict: Словарь с результатами проверки.
"""
proxies = {
"http": proxy_url,
"https": proxy_url,
}
start_time = time.time()
try:
response = requests.get(target_url, proxies=proxies, timeout=timeout)
end_time = time.time()
response.raise_for_status()
try:
data = response.json()
origin_ip = data.get('origin', 'N/A')
except requests.exceptions.JSONDecodeError:
origin_ip = "JSON Decode Error"
return {
"proxy": proxy_url,
"status": "рабочий",
"response_time": round((end_time - start_time) * 1000, 2),
"protocol": "SOCKS", # Определить SOCKS4 или SOCKS5 сложнее без прямого взаимодействия
"origin_ip": origin_ip
}
except requests.exceptions.ConnectionError:
return {"proxy": proxy_url, "status": "отказ соединения", "response_time": None, "protocol": None, "origin_ip": None}
except requests.exceptions.Timeout:
return {"proxy": proxy_url, "status": "таймаут", "response_time": None, "protocol": None, "origin_ip": None}
except requests.exceptions.RequestException as e:
return {"proxy": proxy_url, "status": f"ошибка: {e}", "response_time": None, "protocol": None, "origin_ip": None}
# Пример использования:
# socks_proxy_to_check = "socks5://192.168.1.1:1080" # Замените на реальный SOCKS прокси
# result = check_socks_proxy(socks_proxy_to_check)
# print(result)
Для универсального чекера, который определяет тип прокси, можно сначала попытаться проверить прокси как HTTP/HTTPS, а затем, в случае неудачи, как SOCKS. Однако, более надежный подход — это знать тип прокси заранее из источника или использовать специализированные библиотеки для низкоуровневого хендшейка.
Определение уровня анонимности
Уровень анонимности прокси определяется тем, какую информацию о реальном IP-адресе клиента прокси-сервер передает целевому сайту через HTTP-заголовки. Для определения анонимности чекер должен запросить специальный URL, который возвращает HTTP-заголовки запроса и IP-адрес, видимый целевому серверу. Например, http://httpbin.org/headers или http://ip-api.com/json (для IP).
Классификация уровней анонимности
| Уровень анонимности | Описание ```python
import requests
import time
import concurrent.futures
from typing import List, Dict, Union
Запрещенные AI-паттерны удалены. Стиль: технический справочник.
def get_real_ip(target_url="http://httpbin.org/ip", timeout=5) -> Union[str, None]:
"""
Получает реальный IP-адрес клиента без использования прокси.
Используется для сравнения при определении уровня анонимности.
"""
try:
response = requests.get(target_url, timeout=timeout)
response.raise_for_status()
return response.json().get('origin')
except requests.exceptions.RequestException:
return None
def check_proxy(proxy_address: str, target_url="http://httpbin.org/ip", headers_url="http://httpbin.org/headers", timeout=10, real_ip: str = None) -> Dict[str, Union[str, int, float, bool, None]]:
"""
Проверяет один прокси-сервер на работоспособность, скорость, протокол и уровень анонимности.
Args:
proxy_address (str): Адрес прокси (например, "ip:port").
target_url (str): URL для проверки доступности и получения IP.
headers_url (str): URL для получения HTTP-заголовков, отправленных прокси.
timeout (int): Таймаут в секундах для каждого запроса.
real_ip (str): Реальный IP-адрес клиента, полученный без прокси.
Returns:
dict: Словарь с результатами проверки.
"""
result = {
"proxy": proxy_address,
"status": "неизвестно",
"response_time_ms": None,
"protocol": None,
"origin_ip": None,
"anonymity": None,
"error": None
}
# Пробуем HTTP/HTTPS
http_proxy_url = f"http://{proxy_address}"
https_proxy_url = f"https://{proxy_address}"
proxies_http = {"http": http_proxy_url, "https": https_proxy_url}
# Пробуем SOCKS4/SOCKS5
socks5_proxy_url = f"socks5://{proxy_address}"
socks4_proxy_url = f"socks4://{proxy_address}"
proxies_socks5 = {"http": socks5_proxy_url, "https": socks5_proxy_url}
proxies_socks4 = {"http": socks4_proxy_url, "https": socks4_proxy_url}
test_protocols = [
("HTTP/HTTPS", proxies_http),
("SOCKS5", proxies_socks5),
("SOCKS4", proxies_socks4),
]
for proto_name, current_proxies in test_protocols:
start_time = time.time()
try:
response = requests.get(target_url, proxies=current_proxies, timeout=timeout)
response.raise_for_status()
end_time = time.time()
result["status"] = "рабочий"
result["response_time_ms"] = round((end_time - start_time) * 1000, 2)
result["protocol"] = proto_name
try:
data = response.json()
result["origin_ip"] = data.get('origin')
except requests.exceptions.JSONDecodeError:
result["origin_ip"] = "JSON Decode Error"
# Определение уровня анонимности
if real_ip:
try:
headers_response = requests.get(headers_url, proxies=current_proxies, timeout=timeout)
headers_response.raise_for_status()
headers = headers_response.json().get('headers', {})
if 'Via' in headers or 'X-Forwarded-For' in headers and real_ip in headers['X-Forwarded-For']:
result["anonymity"] = "Transparent"
elif 'X-Forwarded-For' in headers and real_ip not in headers['X-Forwarded-For']:
result["anonymity"] = "Anonymous"
elif result["origin_ip"] != real_ip and not ('Via' in headers or 'X-Forwarded-For' in headers):
result["anonymity"] = "Elite"
else:
result["anonymity"] = "Неизвестно"
except requests.exceptions.RequestException:
result["anonymity"] = "Ошибка при проверке анонимности"
return result # Прокси рабочий, возвращаем результат
except (requests.exceptions.ConnectionError, requests.exceptions.ProxyError):
continue # Пробуем следующий протокол
except requests.exceptions.Timeout:
result["status"] = "таймаут"
result["error"] = f"Таймаут ({proto_name})"
continue
except requests.exceptions.RequestException as e:
result["status"] = "ошибка"
result["error"] = f"Ошибка ({proto_name}): {e}"
continue
# Если ни один протокол не сработал
if result["status"] == "неизвестно":
result["status"] = "нерабочий"
result["error"] = "Не удалось подключиться ни по одному протоколу"
return result
Параллельная проверка прокси
Для эффективной проверки большого списка прокси-серверов необходимо использовать многопоточность или многопроцессорность. concurrent.futures в Python предоставляет высокоуровневый интерфейс для асинхронного выполнения вызовов. ThreadPoolExecutor подходит для I/O-bound задач, таких как сетевые запросы.
from concurrent.futures import ThreadPoolExecutor, as_completed
def check_proxies_concurrently(proxy_list: List[str], max_workers: int = 10, target_url: str = "http://httpbin.org/ip", headers_url: str = "http://httpbin.org/headers", timeout: int = 10) -> List[Dict[str, Union[str, int, float, bool, None]]]:
"""
Параллельно проверяет список прокси-серверов.
Args:
proxy_list (List[str]): Список адресов прокси (например, ["ip1:port1", "ip2:port2"]).
max_workers (int): Максимальное количество параллельных потоков.
target_url (str): Целевой URL для проверки доступности и получения IP.
headers_url (str): URL для получения HTTP-заголовков.
timeout (int): Таймаут в секундах для каждого запроса.
Returns:
List[dict]: Список словарей с результатами проверки для каждого прокси.
"""
print("Получение реального IP-адреса для определения анонимности...")
real_ip = get_real_ip()
if not real_ip:
print("Не удалось получить реальный IP. Определение анонимности может быть неточным.")
else:
print(f"Ваш реальный IP: {real_ip}")
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_proxy = {executor.submit(check_proxy, proxy, target_url, headers_url, timeout, real_ip): proxy for proxy in proxy_list}
for i, future in enumerate(as_completed(future_to_proxy)):
proxy = future_to_proxy[future]
try:
result = future.result()
results.append(result)
print(f"[{i+1}/{len(proxy_list)}] Прокси {proxy}: Статус={result['status']}, Протокол={result['protocol']}, Время={result['response_time_ms']}мс, Анонимность={result['anonymity']}")
except Exception as exc:
print(f"Прокси {proxy} сгенерировал исключение: {exc}")
results.append({"proxy": proxy, "status": "ошибка чекера", "error": str(exc)})
return results
## Дополнительные возможности и лучшие практики
### Целевые URL для проверки
Выбор целевого URL влияет на точность и скорость проверки. Рекомендуется использовать:
* Сервисы, возвращающие IP-адрес клиента (например, `http://httpbin.org/ip`, `https://api.ipify.org?format=json`).
* Сервисы, возвращающие HTTP-заголовки запроса (например, `http://httpbin.org/headers`).
* Сервисы с гео-локацией по IP (например, `http://ip-api.com/json`).
Избегайте сайтов, которые могут блокировать частые запросы или требуют авторизации.
### Обработка ошибок и таймаутов
Надежный чекер должен корректно обрабатывать различные сетевые ошибки (`ConnectionError`, `ProxyError`, `SSLError`) и таймауты (`Timeout`). Установка адекватного таймаута важна: слишком короткий может отсечь медленные, но рабочие прокси; слишком длинный замедлит проверку.
### Ротация User-Agent
Некоторые целевые ресурсы могут блокировать запросы с дефолтным `User-Agent` библиотеки `requests`. Использование случайных `User-Agent` из списка помогает избежать блокировок.
```python
import random
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",
# Добавить другие User-Agent
]
def get_random_user_agent():
return random.choice(USER_AGENTS)
# Использование в запросе:
# headers = {"User-Agent": get_random_user_agent()}
# response = requests.get(target_url, proxies=current_proxies, timeout=timeout, headers=headers)
Детальное логирование
Для отладки и анализа результатов полезно вести подробные логи, записывая не только статус, но и полные сообщения об ошибках, время выполнения и другие метадан