Прокси для Pinterest: массовый парсинг пинов и обход rate-limit
Содержание
- Прокси для Pinterest: массовый парсинг пинов и обход rate-limit
- Как Pinterest определяет ботов
- Почему обычные прокси не работают
- Настройка парсера
- Ротация прокси
- Работа с rate-limit
- Кейс: парсинг 50000 пинов за сутки
- Кейс: обход капчи
- Кейс: баг с геолокацией
- Использование IPv6 прокси
- Таблица сравнения прокси
- Мониторинг и логирование
- Что дальше
Прокси для Pinterest: массовый парсинг пинов и обход rate-limit
Pinterest — одна из самых неудобных площадок для парсинга. Их защита не такая агрессивная, как у Google, но и не такая предсказуемая, как у обычных сайтов. Rate-limit здесь работает по нелинейной логике: можно получить 200 OK на тысячу запросов, а потом внезапно поймать 403 на десятом. Разбираемся, как это работает и что с этим делать.
Как Pinterest определяет ботов
Pinterest использует связку из нескольких механизмов. Во-первых, это анализ User-Agent и TLS-отпечатков. Во-вторых, поведенческий анализ: скорость запросов, паттерны кликов, время между действиями. В-третьих, IP-репутация. Если с одного адреса идёт больше 20-30 запросов в минуту — это уже подозрительно.
Главная особенность Pinterest — они не банят сразу. Сначала ставят мягкий rate-limit: отдают страницы с задержкой 2-5 секунд. Если продолжать долбить — начинают отдавать капчу. И только потом IP уходит в чёрный список.
Почему обычные прокси не работают
Дело в том, что Pinterest активно использует CDN и геолокацию. Если ваш прокси в Германии, а аккаунт зарегистрирован в США — это сразу флаг. Плюс они проверяют consistency: IP должен соответствовать языку браузера, часовому поясу и даже шрифтам в заголовках.
Обычные датацентровые прокси отсеиваются по базе IP-репутации. Резидентские живут дольше, но и они не панацея. Ключевой параметр — соотношение запросов к количеству IP. Для Pinterest это примерно 1 запрос на 5-10 секунд на один IP.
Настройка парсера
Для начала разберём базовую структуру запроса. Pinterest использует GraphQL API, но большинство данных можно получить через обычный HTTP. Вот рабочий пример на Python:
```python
import requests
import time
import random
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.9',
}
PROXIES = {
'http': 'http://user:pass@proxy_ip:port',
'https': 'http://user:pass@proxy_ip:port',
}
def fetch_pins(board_url, max_pages=5):
pins = []
for page in range(max_pages):
try:
response = requests.get(
board_url,
headers=HEADERS,
proxies=PROXIES,
timeout=10
)
if response.status_code == 200:
pins.extend(parse_pins(response.text))
elif response.status_code == 429:
wait = random.uniform(30, 60)
time.sleep(wait)
continue
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
time.sleep(5)
return pins
```
Ключевой момент — обработка 429. Pinterest отдаёт этот код при превышении лимита. Но не всегда. Иногда они просто возвращают пустую страницу с 200 OK. Поэтому нужна проверка на наличие данных в ответе.
Ротация прокси
Простая ротация по кругу не работает. Pinterest запоминает паттерны. Если вы используете 100 прокси и каждый делает по 100 запросов подряд — это выглядит как атака. Правильная стратегия — случайное распределение.
```python
import itertools
import random
class ProxyRotator:
def __init__(self, proxy_list):
self.proxies = proxy_list
self.cycle = itertools.cycle(proxy_list)
self.last_used = {}
def get_proxy(self, url):
while True:
proxy = next(self.cycle)
if self._is_available(proxy):
return proxy
time.sleep(1)
def _is_available(self, proxy):
last = self.last_used.get(proxy, 0)
return time.time() - last > random.uniform(5, 15)
```
Этот подход увеличивает время между запросами с одного IP. Но есть нюанс: Pinterest может отслеживать последовательность IP. Если они идут подряд из одной подсети — это тоже флаг.
Работа с rate-limit
Rate-limit в Pinterest имеет несколько уровней. Первый — 200 запросов в час на IP. Второй — 1000 запросов в день. Третий — поведенческий: если вы запрашиваете одни и те же URL слишком часто.
Реальная история: сервер с 50 прокси делал 10000 запросов в час. Через два часа все IP ушли в бан. Причина — не количество, а отсутствие вариативности. Все запросы шли на одни и те же URL пинов с интервалом 0.5 секунды.
Решение — добавить случайные задержки и менять порядок запросов. Вот как это выглядит:
```python
def fetch_with_backoff(url, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.get(url, headers=HEADERS, proxies=PROXIES)
if response.status_code == 200:
return response
elif response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after + random.uniform(0, 10))
except requests.exceptions.ConnectionError:
time.sleep(5)
return None
```
Заголовок `Retry-After` — ваш друг. Pinterest его отдаёт не всегда, но когда отдаёт — лучше ему верить.
Кейс: парсинг 50000 пинов за сутки
Задача: собрать все пины с 200 досок по теме "дизайн интерьера". Каждая доска содержит 200-300 пинов. Итого — около 50000 URL.
Проблема: стандартный подход с 10 прокси упирается в лимит через 15 минут. Решение — использовать 50 прокси с умной ротацией и распределением нагрузки.
Используем пул из 50 IP, каждый делает не более 20 запросов в минуту. Между запросами — пауза 3-7 секунд. Общее время — 18-20 часов. При этом 5% запросов всё равно ловят 429, но с ретраями они проходят.
Кейс: обход капчи
Pinterest использует reCAPTCHA v3, которая работает без видимых заданий. Она анализирует поведение пользователя. Если скрипт работает слишком ровно — это подозрительно.
Решение — имитация человеческого поведения. Добавляем случайные скроллы, клики по элементам, изменение скорости работы. Это снижает вероятность срабатывания капчи с 30% до 5%.
Пример: вместо равномерных запросов каждые 5 секунд, делаем паузы от 2 до 15 секунд. Иногда отправляем лишние запросы на другие страницы.
Кейс: баг с геолокацией
Столкнулись с ситуацией: прокси в США, но Pinterest отдаёт немецкую версию сайта. Причина — в заголовках Accept-Language. Браузер отправлял `de-DE`, потому что система была на немецком.
Решение — явно указать язык в заголовках:
```python
HEADERS = {
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
}
```
После этого Pinterest начал отдавать английскую версию. Это важно для парсинга, потому что структура HTML может отличаться в зависимости от локали.
Использование IPv6 прокси
IPv6 прокси дают больше возможностей для обхода лимитов. Причина — огромное адресное пространство. У вас может быть /64 подсеть с миллиардами адресов. Но Pinterest не так прост: они группируют IPv6 по префиксам и могут банить всю подсеть.
Практический подход: использовать IPv6 прокси от lexic.ml, которые предоставляют адреса из разных подсетей. Это снижает риск массового бана. Но нужно помнить: не все сайты корректно работают с IPv6. Pinterest — работает, но иногда возникают проблемы с геолокацией.
Таблица сравнения прокси
| Тип прокси | Скорость | Надёжность | Цена | Риск бана |
|------------|----------|------------|------|-----------|
| Датацентровые | Высокая | Низкая | Низкая | Высокий |
| Резидентские | Средняя | Средняя | Средняя | Средний |
| IPv6 | Высокая | Высокая | Низкая | Низкий |
IPv6 прокси выигрывают по соотношению цена/качество. Особенно если нужен большой пул адресов.
Мониторинг и логирование
Без мониторинга парсер развалится. Нужно отслеживать: количество успешных запросов, ошибки 403 и 429, время ответа, количество капч. Всё это — в реальном времени.
```python
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def log_request(url, status, proxy, duration):
logging.info(f"{url} | {status} | {proxy} | {duration:.2f}s")
```
Логи помогают быстро вычислить проблемные прокси. Если один IP даёт 50% ошибок — его нужно заменить.
Что дальше
Pinterest постоянно меняет алгоритмы защиты. То, что работает сегодня, завтра может перестать. Поэтому парсер должен быть гибким: настройки вынесены в конфиг, логика обработки ошибок — модульная. И всегда держите запасные прокси. Это не вопрос "если", а вопрос "когда" — бан придёт.