← Назад в базу знаний

Amazon через IPv6 прокси: мониторинг цен и парсинг отзывов

Amazon через IPv6 прокси: мониторинг цен и парсинг отзывов

Парсинг Amazon — задача, где инфраструктура решает больше, чем сам парсер. Логика извлечения цены умещается в 30 строк, а вот чтобы эти 30 строк отработали 10000 раз без бана — нужен отдельный разговор. Разберём, как IPv6-прокси меняет правила игры, где грабли, и какие цифры реально получаются на выходе.

Почему IPv4-пул умирает за сутки

Классическая схема: берём датацентровый IPv4-прокси, крутим 50 потоков, собираем цены. Amazon отвечает 503 через 2-4 часа. Причина не в User-Agent и не в cookies — в плотности адресов. Один /24 содержит 256 адресов, и если ваш провайдер продаёт этот пул ещё десяти клиентам, Amazon видит кластер из 2560 запросов в минуту с одной подсети.

Система репутации IP у Amazon агрегирует сигналы по ASN и по /24. Даже свежий адрес из «чистого» пула получает пониженный trust score, если соседи уже наследили. Дальше — капча, потом 503, потом тихий бан на уровне TLS-фингерпринта.

IPv6 тут даёт структурное преимущество: провайдер выдаёт /64 на клиента, а это 2^64 адресов. Формально — 18 квинтиллионов. На практике ротация внутри /64 выглядит для антибота как обычный трафик с разных устройств одной сети. Amazon это понимает и относится к /64 мягче, чем к /24 с IPv4.

Как Amazon детектит парсеры в 2024-2025

Защита Amazon — это не один фильтр, а слоёный пирог. Нижний слой — IP-репутация и rate limiting по подсети. Средний — TLS fingerprint (JA3/JA4), HTTP/2 fingerprint, порядок заголовков, наличие `sec-ch-ua` при заявленном Chrome. Верхний — поведенческий: скорость навигации, паттерны кликов, отсутствие загрузки картинок и шрифтов.

Простой `requests` с подменённым UA палится на среднем слое мгновенно: JA3 хэш Python-urllib не совпадает с Chrome, а `Accept-Language: en-US,en;q=0.9` при отсутствии `sec-ch-ua-mobile` — красный флаг. `curl_cffi` с `impersonate="chrome120"` проходит средний слой, но упирается в поведенческий.

```python

from curl_cffi import requests

url = "https://www.amazon.com/dp/B0BDHWDR12"

headers = {

"Accept-Language": "en-US,en;q=0.9",

"Accept-Encoding": "gzip, deflate, br",

}

r = requests.get(

url,

headers=headers,

impersonate="chrome120",

proxies={

"http": "http://user:pass@[2a01:4f8:1c1e:8a3f::1]:8080",

"https": "http://user:pass@[2a01:4f8:1c1e:8a3f::1]:8080",

},

timeout=20,

)

print(r.status_code, len(r.text))

```

Обратите внимание на скобки вокруг IPv6-адреса в URL прокси. Без них `curl` и `requests` пытаются распарсить адрес как host:port и падают с `InvalidURL`. Это грабли №1, на которые наступают все.

Ротация внутри /64: механика

Провайдер выдаёт вам /64. Внутри него можно брать любой адрес — от `2a01:4f8:1c1e:8a3f::1` до `2a01:4f8:1c1e:8a3f:ffff:ffff:ffff:ffff`. Прокси-сервер (3proxy, Squid, HAProxy) слушает на всех или на конкретных адресах, а вы выбираете адрес на каждый запрос.

Ключевой момент: разные /64 — это разные сети с точки зрения Amazon. Разные адреса внутри одного /64 — это одна сеть. Поэтому ротация по адресам внутри /64 помогает от rate limiting, но не от репутации подсети. Если /64 уже «прожжён», меняйте /64 целиком.

```bash

3proxy config для прослушивания на всём /64

/etc/3proxy/3proxy.cfg

nserver 1.1.1.1

nscache 65536

timeouts 1 5 30 60 180 1800 15 60

auth strong

users parser:CL:secret

allow parser

proxy -6 -n -a -p8080 -i2a01:4f8:1c1e:8a3f::1

proxy -6 -n -a -p8081 -i2a01:4f8:1c1e:8a3f::2

proxy -6 -n -a -p8082 -i2a01:4f8:1c1e:8a3f::3

```

Для 256 адресов конфиг руками не пишут — генерируют скриптом. В проде обычно поднимают один прокси с `-i` на весь диапазон и управляют исходящим адресом через `SO_BINDTODEVICE` или параметры сессии.

Что реально стоит проверить перед стартом

Перед тем как запускать сбор цен, проверьте три вещи. Первое — что ваш /64 не в чёрных списках. Второе — что прокси не теряет IPv6-соединение на MTU. Третье — что DNS-резолвинг идёт через тот же адрес, что и HTTP-запрос, иначе Amazon увидит расхождение.

MTU — тихий убийца IPv6. Стандарт для Ethernet — 1500 байт, но туннели и некоторые провайдеры режут до 1280. Если прокси не умеет PMTUD (Path MTU Discovery), большие ответы Amazon (страницы товаров весят 800-1500 КБ) будут зависать на середине.

```bash

Проверка MTU до Amazon через IPv6

ping6 -c 4 -M do -s 1452 www.amazon.com

Если проходит — MTU 1500 OK. Если нет — уменьшайте -s до прохождения.

```

Разница между 1452 и 1400 байт в `-s` — это разница между рабочим парсером и потоком таймаутов. На практике провайдеры IPv6-прокси (в том числе lexic.ml, работающий с 2015 года) держат MTU 1500 и корректный PMTUD, но проверить перед покупкой лишним не будет.

Мониторинг цен: архитектура

Мониторинг — это не «спарсить страницу раз в час». Это система с очередью, дедупликацией и хранением истории. Наивный подход: 10000 ASIN, каждый час, 10000 запросов. Amazon заблокирует за час.

Рабочая схема: 10000 ASIN разбиваются на 10 шардов по 1000. Каждый шард обходится раз в 6 часов с рандомизацией ±30 минут. Итого — 10000 запросов за 6 часов, около 28 запросов в минуту. Это в пределах допустимого для одного /64 при правильной ротации.

```python

import asyncio

from curl_cffi.requests import AsyncSession

async def fetch_price(session, asin, proxy):

url = f"https://www.amazon.com/dp/{asin}"

try:

r = await session.get(url, proxies={"https": proxy}, timeout=15)

if r.status_code == 200:

return asin, extract_price(r.text)

return asin, None

except Exception as e:

return asin, str(e)

async def worker(queue, session, proxy_pool):

while True:

asin = await queue.get()

proxy = proxy_pool.pick()

result = await fetch_price(session, asin, proxy)

await save(result)

await asyncio.sleep(2 + random.uniform(0, 3))

queue.task_done()

async def main(asins):

queue = asyncio.Queue()

for a in asins:

queue.put_nowait(a)

async with AsyncSession(impersonate="chrome120") as s:

tasks = [worker(queue, s, pool) for _ in range(20)]

await asyncio.gather(*tasks)

```

Задержка 2-5 секунд между запросами с одного воркера — не паранойя. Amazon измеряет интервалы и палит «ровный» ритм. Рандомизация ±50% — минимально достаточная.

Извлечение цены: где ломается парсер

Цена на странице Amazon живёт в 4-6 разных местах в зависимости от региона, типа товара и наличия скидки. Селекторы меняются раз в 2-3 месяца. Хардкод `#priceblock_ourprice` не работает с 2021 года.

Рабочий подход — несколько селекторов с приоритетом плюс regex по JSON-LD. JSON-LD (`