Скрейпинг в больших масштабах означает одно: нельзя вручную нажимать «сменить IP» в панели управления каждые 30 секунд. Независимо от того, запускаете ли вы 50 параллельных браузерных сессий, распределённый кластер Scrapy или пайплайн Playwright — ротация IP должна происходить автоматически, через код, а не человека.
Это руководство посвящено именно этому: как использовать API ротации ProxyGrow для программной смены IP мобильного прокси, как проверить смену и как интегрировать всё в реальные сценарии.
Получить доступ к API
Выделенные мобильные прокси с мгновенной API-ротацией IP — Украина, Румыния, Латвия.
Почему API-ротация важна
Резидентные и датацентровые прокси обычно ротируют IP пассивно — новый IP на каждое соединение через пул назначения. Мобильные прокси работают иначе. Каждый модем — это физическое устройство с SIM-картой, постоянно подключённое к сети оператора. Вы получаете статичный IP на сессию, что отлично для управления аккаунтами и сохранения сессий — но это значит, что новый IP нужно запрашивать активно.
Ручная ротация подходит для редкого использования. Она ломается, как только вам нужно:
- Автоматически ротировать после каждых N запросов
- Реагировать на ответ 429 или CAPTCHA сменой IP и повторным запросом
- Запускать параллельные задачи, каждую с чистого IP
- Планировать ротацию по времени без участия человека
Именно здесь приходит API ротации. Один HTTP GET-запрос инициирует переподключение модема, и в течение 3–5 секунд у вас новый IP, назначенный оператором.
Как работает ротация IP в ProxyGrow
ProxyGrow работает на выделенных физических модемах — USB и M.2 4G/5G устройствах, подключённых к серверам в дата-центрах. Каждый модем содержит одну SIM-карту реального оператора (Kyivstar, Vodafone UA, Orange Romania и др.).
Когда вы вызываете API ротации, система отправляет AT-команду (AT+CFUN=1,1 или аналог) на модем, принудительно разрывая соединение с оператором и повторно регистрируясь в сети. Оператор назначает новый IP из своего динамического пула. Весь цикл — отключение, переподключение, получение нового IP — занимает 3 до 5 секунд при обычных условиях сети.
Это настоящая смена IP на уровне оператора, а не перетасовка в пуле прокси. Новый IP — свежий мобильный IP оператора, который ещё не использовался вашей сессией.
Формат ссылки ротации
Каждый выделенный модем в вашем аккаунте ProxyGrow имеет уникальный URL ротации:
http://api.proxygrow.com/rotate?key=YOUR_KEY&modem=MODEM_ID
YOUR_KEY— ваш API-ключ аккаунта, находится в панели управления в разделе API SettingsMODEM_ID— идентификатор конкретного модема (например,modem_01,ua_kyiv_01)
Успешная ротация возвращает HTTP 200 с JSON:
{
"status": "ok",
"modem": "modem_01",
"new_ip": "93.170.xx.xx",
"rotated_at": "2025-06-16T14:23:01Z"
}
При ошибке (неверный ключ, превышен лимит, модем офлайн):
{
"status": "error",
"code": "rate_limit_exceeded",
"retry_after": 60
}
Проверка текущего IP
До или после ротации можно запросить текущий выходной IP любого модема:
http://api.proxygrow.com/ip?key=YOUR_KEY&modem=MODEM_ID
Ответ:
{
"modem": "modem_01",
"ip": "93.170.xx.xx",
"carrier": "Kyivstar",
"country": "UA",
"updated_at": "2025-06-16T14:23:04Z"
}
Используйте этот endpoint, чтобы убедиться, что ротация завершена и IP действительно сменился, прежде чем пускать трафик через прокси.
Пример на Python
Самая распространённая интеграция. Используйте requests для вызова ротации, проверки смены IP и дальнейшей работы.
import requests
import time
API_KEY = "your_api_key_here"
MODEM_ID = "modem_01"
PROXY_HOST = "proxy.proxygrow.com"
PROXY_PORT = 10001
ROTATE_URL = f"http://api.proxygrow.com/rotate?key={API_KEY}&modem={MODEM_ID}"
IP_CHECK_URL = f"http://api.proxygrow.com/ip?key={API_KEY}&modem={MODEM_ID}"
def get_current_ip():
response = requests.get(IP_CHECK_URL, timeout=10)
return response.json().get("ip")
def rotate_ip(max_retries=3):
previous_ip = get_current_ip()
for attempt in range(max_retries):
resp = requests.get(ROTATE_URL, timeout=15)
data = resp.json()
if data.get("status") == "error":
if data.get("code") == "rate_limit_exceeded":
wait = data.get("retry_after", 60)
print(f"Rate limited. Waiting {wait}s before retry...")
time.sleep(wait)
continue
raise RuntimeError(f"Rotation failed: {data}")
# Wait for modem to reconnect
time.sleep(5)
new_ip = get_current_ip()
if new_ip != previous_ip:
print(f"IP rotated: {previous_ip} → {new_ip}")
return new_ip
print(f"IP unchanged after rotation attempt {attempt + 1}, retrying...")
time.sleep(10)
raise RuntimeError("Failed to confirm IP change after rotation")
def scrape_with_rotation(urls):
proxies = {
"http": f"socks5h://{PROXY_HOST}:{PROXY_PORT}",
"https": f"socks5h://{PROXY_HOST}:{PROXY_PORT}",
}
for i, url in enumerate(urls):
if i % 10 == 0 and i > 0:
rotate_ip()
try:
resp = requests.get(url, proxies=proxies, timeout=30)
if resp.status_code == 429:
print(f"Got 429 on {url}, rotating IP and retrying...")
rotate_ip()
resp = requests.get(url, proxies=proxies, timeout=30)
print(f"[{resp.status_code}] {url}")
except Exception as e:
print(f"Error on {url}: {e}")
urls = ["https://example.com/page/1", "https://example.com/page/2"]
scrape_with_rotation(urls)
Пример на Node.js / JavaScript
Для асинхронных задач с нативным fetch (Node 18+):
const API_KEY = 'your_api_key_here';
const MODEM_ID = 'modem_01';
const ROTATE_URL = `http://api.proxygrow.com/rotate?key=${API_KEY}&modem=${MODEM_ID}`;
const IP_CHECK_URL = `http://api.proxygrow.com/ip?key=${API_KEY}&modem=${MODEM_ID}`;
async function getCurrentIp() {
const res = await fetch(IP_CHECK_URL);
const data = await res.json();
return data.ip;
}
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function rotateIp() {
const previousIp = await getCurrentIp();
const res = await fetch(ROTATE_URL);
const data = await res.json();
if (data.status === 'error') {
if (data.code === 'rate_limit_exceeded') {
const waitMs = (data.retry_after || 60) * 1000;
console.log(`Rate limited. Waiting ${data.retry_after}s...`);
await sleep(waitMs);
return rotateIp();
}
throw new Error(`Rotation failed: ${JSON.stringify(data)}`);
}
// Wait for modem reconnect
await sleep(5000);
const newIp = await getCurrentIp();
if (newIp !== previousIp) {
console.log(`IP rotated: ${previousIp} → ${newIp}`);
return newIp;
}
throw new Error('IP did not change after rotation');
}
async function runTask() {
console.log('Rotating IP before task...');
const ip = await rotateIp();
console.log(`Working with IP: ${ip}`);
// Your scraping/automation logic here
}
runTask().catch(console.error);
Пример на Bash / curl
Для быстрых скриптов, cron-задач или shell-пайплайнов:
# Вызов ротации
curl "http://api.proxygrow.com/rotate?key=YOUR_KEY&modem=modem_01"
# Проверка текущего IP
curl "http://api.proxygrow.com/ip?key=YOUR_KEY&modem=modem_01"
# Ротация с ожиданием и проверкой нового IP
curl -s "http://api.proxygrow.com/rotate?key=YOUR_KEY&modem=modem_01" && \
sleep 5 && \
curl -s "http://api.proxygrow.com/ip?key=YOUR_KEY&modem=modem_01" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['ip'])"
Интеграция со Scrapy
Middleware для Scrapy, который ротирует IP после каждых N запросов или при получении ответа 429:
# middlewares.py
import time
import requests
from scrapy import signals
from scrapy.exceptions import IgnoreRequest
class MobileProxyRotationMiddleware:
def __init__(self, api_key, modem_id, rotate_every=20):
self.api_key = api_key
self.modem_id = modem_id
self.rotate_every = rotate_every
self.request_count = 0
self.rotate_url = f"http://api.proxygrow.com/rotate?key={api_key}&modem={modem_id}"
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(
api_key=settings.get("PROXYGROW_API_KEY"),
modem_id=settings.get("PROXYGROW_MODEM_ID"),
rotate_every=settings.getint("PROXYGROW_ROTATE_EVERY", 20),
)
def _rotate(self):
resp = requests.get(self.rotate_url, timeout=15)
data = resp.json()
if data.get("status") == "ok":
time.sleep(5) # Wait for modem reconnect
print(f"Rotated to: {data.get('new_ip')}")
elif data.get("code") == "rate_limit_exceeded":
wait = data.get("retry_after", 60)
print(f"Rate limited, sleeping {wait}s")
time.sleep(wait)
def process_request(self, request, spider):
self.request_count += 1
if self.request_count % self.rotate_every == 0:
self._rotate()
return None
def process_response(self, request, response, spider):
if response.status == 429:
self._rotate()
raise IgnoreRequest(f"429 received, rotated IP, dropping request to retry")
return response
Добавьте в settings.py:
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.MobileProxyRotationMiddleware': 543,
}
PROXYGROW_API_KEY = 'your_api_key_here'
PROXYGROW_MODEM_ID = 'modem_01'
PROXYGROW_ROTATE_EVERY = 20
PROXY_HTTP = 'socks5h://proxy.proxygrow.com:10001'
Интеграция с Playwright / Puppeteer
Ротация прокси между браузерными сессиями — каждая сессия стартует с чистого IP:
// playwright-rotation.js
const { chromium } = require('playwright');
const API_KEY = 'your_api_key_here';
const MODEM_ID = 'modem_01';
async function rotateAndGetIp() {
await fetch(`http://api.proxygrow.com/rotate?key=${API_KEY}&modem=${MODEM_ID}`);
await new Promise(r => setTimeout(r, 5000));
const res = await fetch(`http://api.proxygrow.com/ip?key=${API_KEY}&modem=${MODEM_ID}`);
const data = await res.json();
return data.ip;
}
async function runSession(targetUrl) {
// Rotate IP before launching browser
const ip = await rotateAndGetIp();
console.log(`Starting browser session with IP: ${ip}`);
const browser = await chromium.launch({
proxy: {
server: 'socks5://proxy.proxygrow.com:10001',
},
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(targetUrl);
// ... your automation here
await browser.close();
}
// Run sequential sessions, each with a fresh IP
const urls = ['https://example.com/task/1', 'https://example.com/task/2'];
(async () => {
for (const url of urls) {
await runSession(url);
}
})();
Лимиты ротации
Мобильные сети операторов не рассчитаны на частую повторную регистрацию SIM. Слишком частая ротация создаёт проблемы:
- Оператор может пометить SIM за аномальный паттерн переподключений
- Модему нужно время на поиск сети и повторную регистрацию (минимум 3–5 секунд)
- Некоторые операторы устанавливают задержку перед назначением действительно нового IP
ProxyGrow применяет минимальный интервал 60–120 секунд между ротациями в зависимости от оператора. Попытка ротировать чаще вернёт ошибку rate_limit_exceeded со значением retry_after в секундах.
Практическое правило: планируйте интервалы ротации вокруг структуры задач, а не чистого времени. Ротируйте между логическими блоками задач (набор страниц для одной цели, одна сессия аккаунта, один пакет поисковых запросов), а не после каждого запроса.
Лучшие практики
Не ротируйте в середине сессии. Если вы авторизованы в аккаунте или поддерживаете сессионные cookies, ротация выглядит для сайта как внезапная смена IP — сильный сигнал мошенничества. Ротируйте перед началом сессии, никогда во время.
Ротируйте между логическими задачами. Определите единицы задач (например, «собрать все страницы результатов по ключевому слову X») и ротируйте между ними. Это максимизирует ценность IP и минимизирует лишние ротации.
Проверяйте смену IP. Всегда вызывайте /ip после ротации, чтобы убедиться в наличии нового IP перед отправкой трафика. Иногда модем получает от оператора тот же IP из пула — редко, но бывает.
Отслеживайте репутацию IP. Ведите учёт IP, которые были заблокированы (вернули CAPTCHA или 403). Ротируйте снова, если попали на проблемный IP.
Обрабатывайте ошибки корректно. API ротации может возвращать ошибки — модемы уходят офлайн, лимиты срабатывают. Встройте логику повторных попыток с экспоненциальным откатом в обёртку ротации.
Получить доступ к API
Выделенные мобильные прокси с мгновенной API-ротацией IP — Украина, Румыния, Латвия.
Доступ к API: только на тарифах Dedicated
API ротации доступен исключительно на выделенных тарифных планах (Dedicated). Shared-планы подключают к ротирующему пулу без контроля над отдельными модемами — API ротации на них отсутствует по принципу работы.
На Dedicated-плане вы получаете:
- Собственный физический модем с фиксированной SIM-картой оператора
- Полный доступ к API для ротации, проверки IP и запроса статуса модема
- Гарантированную пропускную способность — без совместного использования с другими пользователями
- Возможность выбирать нужный модем/оператора для каждой задачи
Если вы разрабатываете пайплайн для скрейпинга, инструмент автоматизации или систему управления несколькими аккаунтами, которой нужен программный контроль IP — Dedicated-план правильный выбор.
API ротации прост, стабилен и спроектирован для чистой интеграции с любым языком или фреймворком. Один HTTP GET, пять секунд ожидания — и у вас свежий IP оператора, готовый к следующей задаче.