Скрейпінг у великих масштабах означає одне: не можна вручну натискати «змінити 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 оператора, готовий до наступного завдання.