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

YouTube через IPv6 прокси: парсинг комментариев и аналитика каналов

YouTube через IPv6 прокси: парсинг комментариев и аналитика каналов

Почему YouTube и IPv6 — это отдельная история

YouTube отдаёт контент через Google Global Cache, и если провайдер имеет пиринг с Google, трафик идёт напрямую. Но при массовом парсинге комментариев и метаданных каналов всё ломается: Google видит сотни запросов с одного IPv4 и начинает отдавать 429 или капчу. IPv6 здесь спасает, потому что у каждого запроса может быть свой адрес из /64 или даже /48 — а это 2^64 адресов на одну подсеть.

Проблема в том, что YouTube API v3 для комментариев даёт квоту 10 000 units в день. Один вызов `commentThreads.list` стоит 1 unit, но чтобы вытащить все комментарии под популярным видео (100k+ штук), нужно пройти по nextPageToken десятки раз. Квота кончается за пару часов. Поэтому многие уходят на парсинг HTML через `youtubei/v1/next` — внутренний endpoint, который не требует API-ключа, но требует корректных заголовков и свежих visitor data.

Вот тут и начинается работа с IPv6. Google привязывает visitor data к IP-подсети. Если делать 50 запросов в минуту с одного адреса — получишь `429 Too Many Requests` с заголовком `Retry-After: 3600`. Ротация IPv6 решает это, но не так просто, как кажется.

Как YouTube определяет, что вы — бот

Первый слой защиты — TLS fingerprint. YouTube (как и весь Google) использует JA3/JA4-хэширование. Если вы шлёте запросы через `requests` в Python, TLS-хэндшейк отличается от Chrome 120. Google это видит и может отдать `403` даже без превышения rate limit.

Второй слой — `X-Goog-Visitor-Id` и `X-YouTube-Client-Name`. Без них endpoint `youtubei/v1/next` вернёт `400 Bad Request`. Эти заголовки генерируются при загрузке страницы, и они валидны примерно 2-4 часа.

Третий слой — поведенческий. Если вы запрашиваете только `next` без предварительной загрузки `/watch?v=...`, это выглядит подозрительно. Google логирует последовательность запросов и может пометить сессию.

IPv6-прокси помогает обойти третий слой (каждый запрос с нового адреса = новая сессия), но не первый и не второй. Поэтому нужен зоопарк инструментов: `curl_cffi` для JA3-имитации, ротация visitor data, и IPv6-пул.

Настройка IPv6-прокси для парсинга

Допустим, у вас есть /64 от провайдера (обычно Hetzner или OVH дают /64 бесплатно к VPS). Нужно настроить роутинг так, чтобы исходящие запросы шли с разных адресов.

На Linux это делается через `ip -6 route add local` и NAT66, либо через `ip6tables` с `SNAT`. Вот рабочий конфиг для Debian 12:

```bash

ip -6 route add local 2001:db8:1234::/64 dev lo

sysctl -w net.ipv6.ip_nonlocal_bind=1

```

Теперь можно биндить любой адрес из /64 на сокет. В Python это выглядит так:

```python

import socket

import requests

def get_with_ipv6(ipv6_addr, url):

adapter = requests.adapters.HTTPAdapter()

session = requests.Session()

session.mount('https://', adapter)

class IPv6Adapter(requests.adapters.HTTPAdapter):

def init_poolmanager(self, *args, **kwargs):

kwargs['source_address'] = (ipv6_addr, 0)

return super().init_poolmanager(*args, **kwargs)

session.mount('https://', IPv6Adapter())

return session.get(url, timeout=10)

```

Но `requests` не умеет имитировать TLS fingerprint. Для YouTube нужен `curl_cffi`:

```python

from curl_cffi import requests as cffi_requests

response = cffi_requests.get(

"https://www.youtube.com/watch?v=dQw4w9WgXcQ",

impersonate="chrome120",

proxies={"https": "http://[2001:db8:1234::1]:8080"}

)

```

Прокси должен поддерживать IPv6 binding. Если используете `squid` или `3proxy`, проверьте, что `acl` разрешает IPv6-адресацию.

Реальный кейс: парсинг комментариев под видео с 2M просмотров

Задача: вытащить все комментарии под видео, где 180k комментариев. API v3 даёт 100 комментариев на страницу, значит 1800 запросов. Квота — 10 000 units, один `commentThreads.list` = 1 unit. Хватит, но только на это видео.

Решение через `youtubei/v1/next` с IPv6-ротацией. Каждый запрос идёт с нового адреса из /64. Заголовки:

```

X-Goog-Visitor-Id: Cgta...

X-YouTube-Client-Name: 1

X-YouTube-Client-Version: 2.20240101.00.00

Content-Type: application/json

```

Тело запроса — continuation token из предыдущего ответа. Без правильного visitor data Google вернёт `400`. Visitor data получается при первом запросе к `/watch`, и он валиден 2-4 часа.

Проблема: если делать 1800 запросов за 10 минут, Google всё равно увидит паттерн. Даже с ротацией IPv6. Потому что continuation tokens связаны между собой — Google знает, что это одна сессия парсинга.

Решение — разбить на батчи по 50 запросов, между батчами пауза 30-60 секунд, и каждый батч с нового visitor data. Это замедляет парсинг (1800 запросов = 36 батчей = ~30 минут), но снижает риск бана.

Аналитика каналов: что можно вытащить без API

Через `youtubei/v1/browse` можно получить список видео канала, количество подписчиков, дату регистрации, и даже примерный доход (если канал монетизирован и вы знаете CPM). Endpoint требует `browseId` канала (начинается с `UC...`).

Запрос:

```bash

curl -X POST "https://www.youtube.com/youtubei/v1/browse?key=AIzaSy..." \

-H "Content-Type: application/json" \

-H "X-Goog-Visitor-Id: Cgta..." \

-d '{

"context": {

"client": {

"clientName": "WEB",

"clientVersion": "2.20240101.00.00"

}

},

"browseId": "UCuAXFkgsw1L7xaCfnd5JJOw"

}'

```

Ответ — JSON на 200-500 KB. Там есть `subscriberCountText`, `videosCountText`, и список видео с `viewCountText`. Парсинг — через `jq` или Python.

Но есть нюанс: YouTube отдаёт разные данные для разных стран. Если запрос идёт с IPv6 из Германии, а канал — американский, вы увидите `viewCount` для DE-региона. Это может отличаться на 5-15% от реального.

Сравнение подходов: API vs HTML vs youtubei

| Метод | Лимит | Скорость | Риск бана | Данные |

|-------|-------|----------|-----------|--------|

| API v3 | 10k units/день | 100 комментов/запрос | Низкий | Полные |

| HTML парсинг | Нет лимита | 20 комментов/страница | Средний | Урезанные |

| youtubei/v1 | Нет лимита | 100 комментов/запрос | Высокий | Полные |

| yt-dlp | Нет лимита | 100 комментов/запрос | Средний | Полные |

`yt-dlp` — это отдельная история. Он использует `youtubei/v1` под капотом, но с правильными заголовками и автоматическим обновлением visitor data. Если вам нужно быстро и без банов — `yt-dlp` с `--extractor-args "youtube:player_client=web"` и IPv6-прокси.

Почему IPv6-ротация работает не всегда

Google использует не только IP, но и `X-Forwarded-For`, `X-Real-IP`, и даже `Client Hints`. Если прокси не подменяет эти заголовки, Google видит реальный IP.

Второй момент — ASN. Если все ваши IPv6 из одной /64, Google видит один ASN. Это не проблема, если ASN — Hetzner или OVH. Но если это residential proxy с /64 от Comcast — Google может пометить весь пул.

Третий момент — DNS. Если вы используете IPv6-прокси, но DNS-запросы идут через IPv4, Google видит несоответствие. Нужно настроить DNS over IPv6 или использовать `--dns-servers` в `curl`.

Кейс: 429 после 200 запросов с одного /64

Ситуация: сервер на Hetzner с /64, 200 запросов к `youtubei/v1/next` за 5 минут. На 201-м запросе — `429 Too Many Requests`.

Причина: Google агрегирует запросы по /64, а не по отдельным адресам. 200 запросов с 200 разных адресов из одной /64 = 200 запросов с одной подсети.

Решение: использовать /48 вместо /64. Hetzner даёт /48 за дополнительную плату (€5/месяц). Это 2^80 адресов, и Google не может агрегировать их все.

Альтернатива: ротация visitor data каждые 50 запросов. Это сбрасывает счётчик на стороне Google, потому что новый visitor data = новая сессия.

Кейс: 403 при парсинге через curl_cffi

Ситуация: `curl_cffi` с `impersonate="chrome120"` возвращает `403` на `youtubei/v1/next`. При этом `yt-dlp` с теми же прокси работает.

Причина: `curl_cffi` не отправляет заголовок `X-YouTube-Client-Version`. Без него Google отдаёт `403`.

Решение: добавить заголовки вручную:

```python

headers = {

"X-YouTube-Client-Name": "1",

"X-YouTube-Client-Version": "2.20240101.00.00",

"X-Goog-Visitor-Id": visitor_id,

"Content-Type": "application/json"

}

```

Проверка: после добавления заголовков `403` исчез, скорость парсинга — 120 запросов/минуту с ротацией IPv6.

Кейс: неполные комментарии при парсинге через HTML

Ситуация: парсинг HTML страницы `/watch` даёт только 20 комментариев, хотя под видео их 5000+.

Причина: YouTube загружает комментарии через AJAX после загрузки страницы. В HTML есть только первые 20, остальные — через `youtubei/v1/next`.

Решение: использовать `youtubei/v1/next` с continuation token из HTML. Токен лежит в `ytInitialData`. Парсинг через `json.loads(re.search(r'ytInitialData = ({.*?});', html).group(1))`.

Сложность: структура `ytInitialData` меняется каждые 2-3 месяца. Нужно регулярно обновлять парсер.

Инструменты: что использовать в 2024

`yt-dlp` — для быстрого старта. Поддерживает IPv6-прокси, автоматически обновляет visitor data, умеет вытаскивать комментарии через `--write-comments`.

`curl_cffi` — для кастомных запросов. Имитирует JA3 Chrome, поддерживает IPv6 binding.

`playwright` — если нужно эмулировать полный браузер. Медленно (2-3 секунды на запрос), но обходит все защиты.

`scrapy` с `scrapy-rotating-proxies` — для масштабного парсинга. Поддерживает IPv6, но требует настройки middleware.

Вот пример на `yt-dlp` с IPv6-прокси:

```bash

yt-dlp --write-comments \

--extractor-args "youtube:player_client=web" \

--proxy "http://[2001:db8:1234::1]:8080" \

--sleep-requests 1 \

--max-comments 1000 \

"https://www.youtube.com/watch?v=dQw4w9WgXcQ"

```

`--sleep-requests 1` добавляет паузу 1 секунда между запросами. Это снижает риск бана, но замедляет парсинг.

Архитектура: как построить пайплайн

Пайплайн для парсинга 10 000 видео:

1. Очередь видео (Redis или RabbitMQ).

2. Воркеры на Python с `curl_cffi` и IPv6-прокси.

3. Ротация visitor data каждые 50 запросов.

4. Сохранение в PostgreSQL с индексами по `video_id` и `comment_id`.

5. Мониторинг 429/403 через Prometheus.

Ключевой момент — не делать все запросы с одного IP. Даже с IPv6. Если у вас 10 воркеров, каждый должен использовать свой /64 или хотя бы свой /80.

Что дальше

YouTube будет ужесточать защиту. Уже сейчас `youtubei/v1/next` требует свежий visitor data, а `yt-dlp` обновляется каждые 2-3 недели. IPv6-ротация — это не панацея, а один из инструментов.

Если вам нужен стабильный парсинг, смотрите в сторону residential IPv6 (дорого, но надёжно) или используйте API с несколькими ключами (10 ключей = 100k units/день).

Для аналитики каналов хватит `youtubei/v1/browse` с ротацией IPv6. Для комментариев — `yt-dlp` с `--write-comments` и паузами. Для масштаба — свой пайплайн на `curl_cffi` с /48 и ротацией visitor data.

Прокси-сервисы вроде lexic.ml дают IPv6-пулы с /64 и /48, что снимает головную боль с настройкой роутинга. Но даже с хорошим пулом нужно следить за заголовками и visitor data — иначе Google забанят всю подсеть за пару часов.

✔️Купить прокси