ProxyGrow LogoProxyGrow

2025-06-16 · 8 min read

API ротации IP мобильного прокси: автоматизируем смену IP

Полное руководство по использованию API ротации мобильного прокси. Смена IP через HTTP-запрос, интеграция с Python, Node.js и другими языками. Реальные примеры кода.

Скрейпинг в больших масштабах означает одно: нельзя вручную нажимать «сменить IP» в панели управления каждые 30 секунд. Независимо от того, запускаете ли вы 50 параллельных браузерных сессий, распределённый кластер Scrapy или пайплайн Playwright — ротация IP должна происходить автоматически, через код, а не человека.

Это руководство посвящено именно этому: как использовать API ротации ProxyGrow для программной смены IP мобильного прокси, как проверить смену и как интегрировать всё в реальные сценарии.

Получить доступ к API

Выделенные мобильные прокси с мгновенной API-ротацией IP — Украина, Румыния, Латвия.

Real 4G/5G IPsSOCKS5 / HTTP / UDP / VLESSUSDT paymentsFast activation
Get Started Now → @ProxyGrow

Почему 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 Settings
  • MODEM_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 — Украина, Румыния, Латвия.

Real 4G/5G IPsSOCKS5 / HTTP / UDP / VLESSUSDT paymentsFast activation
Get Started Now → @ProxyGrow

Доступ к API: только на тарифах Dedicated

API ротации доступен исключительно на выделенных тарифных планах (Dedicated). Shared-планы подключают к ротирующему пулу без контроля над отдельными модемами — API ротации на них отсутствует по принципу работы.

На Dedicated-плане вы получаете:

  • Собственный физический модем с фиксированной SIM-картой оператора
  • Полный доступ к API для ротации, проверки IP и запроса статуса модема
  • Гарантированную пропускную способность — без совместного использования с другими пользователями
  • Возможность выбирать нужный модем/оператора для каждой задачи

Если вы разрабатываете пайплайн для скрейпинга, инструмент автоматизации или систему управления несколькими аккаунтами, которой нужен программный контроль IP — Dedicated-план правильный выбор.

API ротации прост, стабилен и спроектирован для чистой интеграции с любым языком или фреймворком. Один HTTP GET, пять секунд ожидания — и у вас свежий IP оператора, готовый к следующей задаче.

Ready to get real mobile proxies?

Ukraine · Romania · Latvia — 4G/5G carrier IPs, instant activation.