[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ru-rotaciya-proksi-v-colly-1":3},{"success":4,"payload":5,"related":60,"errors":154},true,{"id":6,"slug":7,"title":8,"excerpt":9,"body_html":10,"meta_title":11,"meta_description":12,"canonical_url":13,"canonical_override":14,"og_title":11,"og_description":15,"og_image_url":16,"faq_json":17,"key_takeaways":14,"allow_index":27,"noindex_google_only":27,"allow_follow":4,"published_at":28,"updated_at":28,"content_updated_at":29,"featured_image_url":30,"featured_image_alt":31,"card_image_url":32,"reading_time_minutes":33,"author":34,"categories":38,"tags":45,"alternates":46,"locale_paths":58,"views":59},175,"rotaciya-proksi-v-colly-1","Ротация прокси в Colly: Полное руководство для Go-разработчиков","Практическое руководство по ротации прокси в Colly — от встроенного RoundRobinProxySwitcher до кастомных SetProxyFunc с резидентными IP. Примеры кода, продакшн-паттерны и типичные ошибки.","\u003Cp>Ротация прокси в Colly — ключевой навык для любого Go-разработчика, который строит высоконагруженный скрейпер. Colly — быстрый и элегантный фреймворк, но без правильной настройки прокси ваш коллектор получит HTTP 403 или CAPTCHA уже после первых десятков запросов. В этом руководстве мы разберём, как использовать \u003Ccode>proxy.RoundRobinProxySwitcher\u003C\u002Fcode> и \u003Ccode>c.SetProxyFunc\u003C\u002Fcode> с резидентными IP, как интегрировать \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat\u003C\u002Fa> и какие продакшн-паттерны применять для масштабирования.\u003C\u002Fp>\n\n\u003Cblockquote>\u003Cstrong>Важно:\u003C\u002Fstrong> Эта статья посвящена сбору публично доступных данных. Сбор данных может регулироваться \u003Ca href=\"https:\u002F\u002Fwww.ftc.gov\u002Flegal-library\u002Fbrowse\u002Fcases-proceedings\" rel=\"noopener noreferrer\">CFAA (США)\u003C\u002Fa> и \u003Ca href=\"https:\u002F\u002Fgdpr-info.eu\u002F\" rel=\"noopener noreferrer\">GDPR (ЕС)\u003C\u002Fa>. Всегда соблюдайте robots.txt, условия обслуживания сайтов и местное законодательство. Информация здесь — не юридическая консультация.\u003C\u002Fblockquote>\n\n\u003Ch2>Почему ротация прокси в Colly необходима\u003C\u002Fh2>\n\n\u003Cp>Colly отправляет HTTP-запросы через стандартный \u003Ccode>net\u002Fhttp\u003C\u002Fcode> клиент Go. По умолчанию все запросы идут с одного IP-адреса вашей машины. Современные антибот-системы — Cloudflare, Akamai Bot Manager, PerimeterX — анализируют поведение и быстро блокируют IP, с которого поступает аномальный трафик. Типичный порог — 50–200 запросов с одного IP за короткий промежуток времени.\u003C\u002Fp>\n\n\u003Cp>Ротация прокси решает эту проблему, распределяя запросы по пулу IP-адресов. \u003Ca href=\"\u002Fru\u002Fuse-cases\u002Fweb-scraping\">Веб-скрейпинг\u003C\u002Fa> с ротацией резидентных прокси снижает риск блокировок до минимума, поскольку каждый запрос выглядит как отдельный пользователь из реального ISP.\u003C\u002Fp>\n\n\u003Ch3>Типы прокси: сравнение\u003C\u002Fh3>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Тип прокси\u003C\u002Fth>\u003Cth>Детектируемость\u003C\u002Fth>\u003Cth>Скорость\u003C\u002Fth>\u003Cth>Стоимость\u003C\u002Fth>\u003Cth>Подходит для\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Datacenter\u003C\u002Ftd>\u003Ctd>Высокая\u003C\u002Ftd>\u003Ctd>Высокая (&lt;50ms)\u003C\u002Ftd>\u003Ctd>Низкая (~$1\u002FGB)\u003C\u002Ftd>\u003Ctd>Простые сайты, API\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Residential\u003C\u002Ftd>\u003Ctd>Низкая\u003C\u002Ftd>\u003Ctd>Средняя (100–500ms)\u003C\u002Ftd>\u003Ctd>Средняя (~$5–15\u002FGB)\u003C\u002Ftd>\u003Ctd>SERP, e-commerce, соцсети\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Mobile\u003C\u002Ftd>\u003Ctd>Очень низкая\u003C\u002Ftd>\u003Ctd>Низкая (300–1000ms)\u003C\u002Ftd>\u003Ctd>Высокая (~$20–50\u002FGB)\u003C\u002Ftd>\u003Ctd>Жёсткие антибот-системы\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>Резидентные прокси — оптимальный баланс для большинства задач \u003Ca href=\"\u002Fru\u002Fuse-cases\u002Fserp-tracking\">SERP-трекинга\u003C\u002Fa> и парсинга e-commerce. Они используют реальные IP-адреса провайдеров, что делает их практически неотличимыми от обычных пользователей.\u003C\u002Fp>\n\n\u003Ch2>Модель коллектора Colly: OnRequest, OnHTML, OnError\u003C\u002Fh2>\n\n\u003Cp>Colly построен вокруг \u003Ccode>colly.Collector\u003C\u002Fcode> — структуры, которая управляет очередью запросов, HTTP-клиентом и callback-хуками. Понимание модели коллектора критично для правильной интеграции прокси.\u003C\u002Fp>\n\n\u003Ch3>Callback-хуки\u003C\u002Fh3>\n\n\u003Cp>Colly предоставляет несколько хуков, которые вызываются на разных стадиях жизненного цикла запроса:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Ccode>OnRequest(func(*colly.Request))\u003C\u002Fcode> — вызывается перед отправкой. Здесь можно установить заголовки, изменить URL, логировать.\u003C\u002Fli>\n\u003Cli>\u003Ccode>OnResponse(func(*colly.Response))\u003C\u002Fcode> — вызывается после получения ответа.\u003C\u002Fli>\n\u003Cli>\u003Ccode>OnHTML(goquerySelector, func(*colly.HTMLElement))\u003C\u002Fcode> — вызывается для каждого элемента,匹配ающего селектору. Использует \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FPuerkitoBio\u002Fgoquery\" rel=\"noopener noreferrer\">goquery\u003C\u002Fa> для DOM-обхода.\u003C\u002Fli>\n\u003Cli>\u003Ccode>OnError(func(*colly.Response, error))\u003C\u002Fcode> — вызывается при ошибке запроса.\u003C\u002Fli>\n\u003Cli>\u003Ccode>OnScraped(func(*colly.Response))\u003C\u002Fcode> — вызывается после полной обработки ответа.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Асинхронный режим включается вызовом \u003Ccode>c.Async = true\u003C\u002Fcode>. В этом режиме Colly использует горутины для параллельной обработки запросов, что критично для производительности, но требует осторожной настройки \u003Ccode>Limit()\u003C\u002Fcode> и ротации прокси.\u003C\u002Fp>\n\n\u003Ch2>Идиоматическая поверхность прокси: RoundRobinProxySwitcher и SetProxyFunc\u003C\u002Fh2>\n\n\u003Cp>Colly предоставляет два способа работы с прокси: встроенный \u003Ccode>proxy.RoundRobinProxySwitcher\u003C\u002Fcode> и кастомная функция через \u003Ccode>c.SetProxyFunc\u003C\u002Fcode>. Оба принимают \u003Ccode>func(*http.Request) (*url.URL, error)\u003C\u002Fcode> — функцию, которая возвращает URL прокси для конкретного запроса.\u003C\u002Fp>\n\n\u003Ch3>RoundRobinProxySwitcher — простой round-robin\u003C\u002Fh3>\n\n\u003Cp>Встроенный свитчер принимает список URL прокси и поочерёдно назначает их запросам. Поддерживает \u003Ccode>http\u003C\u002Fcode>, \u003Ccode>https\u003C\u002Fcode> и \u003Ccode>socks5\u003C\u002Fcode> схемы:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>package main\n\nimport (\n    &quot;fmt&quot;\n    &quot;log&quot;\n    &quot;net\u002Furl&quot;\n\n    &quot;github.com\u002Fgocolly\u002Fcolly&quot;\n    &quot;github.com\u002Fgocolly\u002Fcolly\u002Fproxy&quot;\n)\n\nfunc main() {\n    c := colly.NewCollector()\n\n    proxies := []string{\n        &quot;http:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:8080&quot;,\n        &quot;http:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:8080&quot;,\n        &quot;http:\u002F\u002Fuser-country-GB:pass@gate.proxyhat.com:8080&quot;,\n    }\n\n    rp, err := proxy.RoundRobinProxySwitcher(proxies...)\n    if err != nil {\n        log.Fatal(err)\n    }\n    c.SetProxyFunc(rp)\n\n    c.OnHTML(&quot;title&quot;, func(e *colly.HTMLElement) {\n        fmt.Println(e.Text)\n    })\n\n    c.Visit(&quot;https:\u002F\u002Fhttpbin.org\u002Fip&quot;)\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Это базовый подход, но он имеет ограничение: список прокси фиксирован на старте. Для динамической ротации с гео-таргетингом и sticky-сессиями нужен кастомный свитчер.\u003C\u002Fp>\n\n\u003Ch3>Кастомный SetProxyFunc — полный контроль\u003C\u002Fh3>\n\n\u003Cp>Интерфейс \u003Ccode>c.SetProxyFunc\u003C\u002Fcode> принимает любую функцию с сигнатурой \u003Ccode>func(*http.Request) (*url.URL, error)\u003C\u002Fcode>. Это позволяет реализовать любую логику ротации — round-robin, random, sticky-сессии, гео-таргетинг по домену:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>package main\n\nimport (\n    &quot;fmt&quot;\n    &quot;log&quot;\n    &quot;math\u002Frand&quot;\n    &quot;net\u002Furl&quot;\n    &quot;sync\u002Fatomic&quot;\n\n    &quot;github.com\u002Fgocolly\u002Fcolly&quot;\n)\n\nvar counter uint64\n\nfunc proxySwitcher(req *http.Request) (*url.URL, error) {\n    countries := []string{&quot;US&quot;, &quot;DE&quot;, &quot;GB&quot;, &quot;FR&quot;, &quot;JP&quot;}\n    idx := atomic.AddUint64(&amp;counter, 1) % uint64(len(countries))\n    country := countries[idx]\n\n    \u002F\u002F Уникальная сессия для каждого запроса\n    session := fmt.Sprintf(&quot;sess-%d&quot;, atomic.LoadUint64(&amp;counter))\n\n    proxyURL := fmt.Sprintf(\n        &quot;http:\u002F\u002Fuser-country-%s-sid-%s:pass@gate.proxyhat.com:8080&quot;,\n        country, session,\n    )\n    return url.Parse(proxyURL)\n}\n\nfunc main() {\n    c := colly.NewCollector()\n    c.SetProxyFunc(proxySwitcher)\n\n    c.OnResponse(func(r *colly.Response) {\n        fmt.Printf(&quot;Status: %d, Body: %s\\n&quot;, r.StatusCode, string(r.Body[:100]))\n    })\n\n    for i := 0; i &lt; 10; i++ {\n        c.Visit(&quot;https:\u002F\u002Fhttpbin.org\u002Fip&quot;)\n    }\n    c.Wait()\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Резидентные прокси для сложных целей: гео-таргетинг и сессии\u003C\u002Fh2>\n\n\u003Cp>ProxyHat кодирует параметры гео-таргетинга и сессий прямо в username. Это означает, что каждый запрос может использовать разные параметры без отдельного пула прокси-URL — достаточно динамически формировать строку username.\u003C\u002Fp>\n\n\u003Ch3>Форматы username\u003C\u002Fh3>\n\n\u003Cul>\n\u003Cli>\u003Ccode>user-country-DE:pass\u003C\u002Fcode> — IP из Германии\u003C\u002Fli>\n\u003Cli>\u003Ccode>user-country-DE-region-state_of_berlin-city-berlin:pass\u003C\u002Fcode> — IP из Берлина\u003C\u002Fli>\n\u003Cli>\u003Ccode>user-sid-abc123:pass\u003C\u002Fcode> — sticky-сессия (один IP для всех запросов с этой сессией)\u003C\u002Fli>\n\u003Cli>\u003Ccode>user-country-DE-sid-abc123:pass\u003C\u002Fcode> — комбинированный режим\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Sticky-сессии особенно важны для многостраничного скрейпинга — например, пагинации каталога, где каждый запрос должен идти с того же IP, чтобы сервер «запомнил» вашу корзину или сессию.\u003C\u002Fp>\n\n\u003Ch2>Runnable-пример: коллектор с резидентной ротацией, Limit и custom switcher\u003C\u002Fh2>\n\n\u003Cp>Полный пример с Limit-правилами, асинхронным режимом и кастомным свитчером, читающим список стран:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>package main\n\nimport (\n    &quot;encoding\u002Fjson&quot;\n    &quot;fmt&quot;\n    &quot;log&quot;\n    &quot;net\u002Fhttp&quot;\n    &quot;net\u002Furl&quot;\n    &quot;sync\u002Fatomic&quot;\n    &quot;time&quot;\n\n    &quot;github.com\u002Fgocolly\u002Fcolly&quot;\n)\n\ntype ProxyConfig struct {\n    Username string\n    Password string\n    Gateway  string\n    Port     int\n}\n\ntype SmartSwitcher struct {\n    config   ProxyConfig\n    counter  uint64\n    countries []string\n}\n\nfunc (s *SmartSwitcher) GetProxy(req *http.Request) (*url.URL, error) {\n    idx := atomic.AddUint64(&amp;s.counter, 1) % uint64(len(s.countries))\n    country := s.countries[idx]\n    session := fmt.Sprintf(&quot;sess-%d-%d&quot;, time.Now().Unix(), atomic.LoadUint64(&amp;s.counter))\n\n    proxyStr := fmt.Sprintf(&quot;http:\u002F\u002F%s-country-%s-sid-%s:%s@%s:%d&quot;,\n        s.config.Username, country, session,\n        s.config.Password, s.config.Gateway, s.config.Port,\n    )\n    return url.Parse(proxyStr)\n}\n\nfunc main() {\n    switcher := &amp;SmartSwitcher{\n        config: ProxyConfig{\n            Username: &quot;youruser&quot;,\n            Password: &quot;yourpass&quot;,\n            Gateway:  &quot;gate.proxyhat.com&quot;,\n            Port:     8080,\n        },\n        countries: []string{&quot;US&quot;, &quot;DE&quot;, &quot;GB&quot;, &quot;FR&quot;, &quot;NL&quot;, &quot;JP&quot;},\n    }\n\n    c := colly.NewCollector(\n        colly.Async(true),\n    )\n    c.SetProxyFunc(switcher.GetProxy)\n\n    \u002F\u002F Лимиты: домен, параллелизм, задержка\n    c.Limit(&amp;colly.LimitRule{\n        DomainGlob:  &quot;*httpbin.org&quot;,\n        Parallelism: 5,\n        Delay:       2 * time.Second,\n        RandomDelay: 1 * time.Second,\n    })\n\n    results := make([]string, 0)\n    var mu sync.Mutex\n\n    c.OnHTML(&quot;body&quot;, func(e *colly.HTMLElement) {\n        mu.Lock()\n        defer mu.Unlock()\n        results = append(results, e.Text)\n    })\n\n    c.OnError(func(r *colly.Response, err error) {\n        log.Printf(&quot;Error on %s: %v&quot;, r.Request.URL, err)\n    })\n\n    for i := 0; i &lt; 20; i++ {\n        c.Visit(fmt.Sprintf(&quot;https:\u002F\u002Fhttpbin.org\u002Fip?req=%d&quot;, i))\n    }\n    c.Wait()\n\n    for i, r := range results {\n        fmt.Printf(&quot;Result %d: %s\\n&quot;, i, r)\n    }\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Ключевые моменты этого примера:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>Parallelism: 5\u003C\u002Fcode> — не более 5 одновременных запросов на домен.\u003C\u002Fli>\n\u003Cli>\u003Ccode>Delay: 2 * time.Second\u003C\u002Fcode> с \u003Ccode>RandomDelay: 1 * time.Second\u003C\u002Fcode> — каждый запрос задерживается на 2–3 секунды.\u003C\u002Fli>\n\u003Cli>Каждый запрос получает уникальную сессию и страну — максимальная ротация.\u003C\u002Fli>\n\u003Cli>\u003Ccode>c.Wait()\u003C\u002Fcode> — ожидание завершения всех асинхронных запросов.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Продакшн-паттерны: ретраи, TLS, распределённое скрейпинг\u003C\u002Fh2>\n\n\u003Ch3>Ретраи через c.Clone()\u003C\u002Fh3>\n\n\u003Cp>Colly не имеет встроенного механизма ретраев, но идиоматичный паттерн — клонирование коллектора в \u003Ccode>OnError\u003C\u002Fcode>. Клон наследует настройки прокси, но получает свежий HTTP-клиент:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>var retryCount = make(map[string]int)\nvar maxRetries = 3\n\nc.OnError(func(r *colly.Response, err error) {\n    urlStr := r.Request.URL.String()\n    if retryCount[urlStr] &lt; maxRetries {\n        retryCount[urlStr]++\n        log.Printf(&quot;Retry %d for %s&quot;, retryCount[urlStr], urlStr)\n        \u002F\u002F Клон наследует SetProxyFunc\n        r.Request.Ctx.Put(&quot;retry&quot;, retryCount[urlStr])\n        c.Clone().Visit(urlStr)\n    } else {\n        log.Printf(&quot;Max retries reached for %s&quot;, urlStr)\n    }\n})\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Кастомный Transport с TLS-конфигурацией\u003C\u002Fh3>\n\n\u003Cp>Некоторые сайты требуют специфичных TLS-настроек. Colly позволяет заменить \u003Ccode>http.Transport\u003C\u002Fcode> через \u003Ccode>c.WithTransport()\u003C\u002Fcode>:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import (\n    &quot;crypto\u002Ftls&quot;\n    &quot;net\u002Fhttp&quot;\n)\n\nc.WithTransport(&amp;http.Transport{\n    TLSClientConfig: &amp;tls.Config{\n        InsecureSkipVerify: false,\n        MinVersion:         tls.VersionTLS12,\n        MaxVersion:         tls.VersionTLS13,\n    },\n    MaxIdleConns:        100,\n    MaxIdleConnsPerHost: 10,\n    IdleConnTimeout:    30 * time.Second,\n})\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Распределённый скрейпинг через Redis-очередь\u003C\u002Fh3>\n\n\u003Cp>Colly поддерживает \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fgocolly\u002Fcolly#storage\" rel=\"noopener noreferrer\">несколько storage-бэкендов\u003C\u002Fa> для распределённой работы. Redis-бэкенд позволяет нескольким инстансам Colly разделять очередь URL и cookies:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import (\n    &quot;github.com\u002Fgocolly\u002Fredisstorage&quot;\n    &quot;github.com\u002Fgocolly\u002Fcolly&quot;\n)\n\nstorage := &amp;redisstorage.Storage{\n    Address:  &quot;redis:\u002F\u002Flocalhost:6379&quot;,\n    Prefix:   &quot;colly_scraper&quot;,\n    Client:   nil, \u002F\u002F auto-create\n}\n\nif err := storage.Init(); err != nil {\n    log.Fatal(err)\n}\n\nc := colly.NewCollector()\nc.SetStorage(storage)\n\n\u002F\u002F Несколько инстансов Colly на разных машинах\n\u002F\u002F будут разделять одну очередь URL\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Это позволяет масштабировать скрейпер горизонтально — несколько контейнеров или VM, каждый со своим пулом прокси, но с единой координацией через Redis. Для контейнеризации удобен Docker с переменными окружения для credentials:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode># Dockerfile\nFROM golang:1.22-alpine AS builder\nWORKDIR \u002Fapp\nCOPY . .\nRUN go mod download &amp;&amp; go build -o scraper .\u002Fcmd\u002Fscraper\n\nFROM alpine:3.19\nCOPY --from=builder \u002Fapp\u002Fscraper \u002Fusr\u002Flocal\u002Fbin\u002Fscraper\nENV PROXYHAT_USER=youruser\nENV PROXYHAT_PASS=yourpass\nCMD [&quot;scraper&quot;]\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Контейнерный флот\u003C\u002Fh3>\n\n\u003Cp>Для высоконагруженного скрейпинга эффективен подход «headless-флот» — несколько Docker-контейнеров, каждый со своим инстансом Colly и своим набором стран. Kubernetes или Docker Compose управляют оркестрацией. Каждый контейнер можно настроить на свой регион через переменные окружения, а Redis-бэкенд координирует распределение URL.\u003C\u002Fp>\n\n\u003Ch2>Когда НЕ использовать Colly\u003C\u002Fh2>\n\n\u003Cp>Colly — HTTP-клиент, не браузер. Если целевой сайт рендерит контент через JavaScript (React, Vue, Angular SPA), Colly не выполнит JS и не получит динамический контент. В таких случаях нужен \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fchromedp\u002Fchromedp\" rel=\"noopener noreferrer\">chromedp\u003C\u002Fa> или Playwright для Go.\u003C\u002Fp>\n\n\u003Cp>Признаки, что Colly не подходит:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Контент загружается через XHR\u002Ffetch после загрузки страницы.\u003C\u002Fli>\n\u003Cli>Сайт требует выполнения JavaScript для отображения данных.\u003C\u002Fli>\n\u003Cli>Антибот-система требует отрисовки canvas или WebGL-фингерпринта.\u003C\u002Fli>\n\u003Cli>Нужна эмуляция скроллинга или кликов.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>В этих сценариях комбинируйте Colly для статичных страниц с headless-браузером для JS-зависимых. Прокси-ротация в chromedp настраивается через \u003Ccode>--proxy-server\u003C\u002Fcode> флаг Chrome.\u003C\u002Fp>\n\n\u003Ch2>Этика и правовые аспекты\u003C\u002Fh2>\n\n\u003Cp>Сбор публичных данных — законная деятельность, но с ограничениями. Ключевые принципы:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>Соблюдайте robots.txt.\u003C\u002Fstrong> Colly может автоматически читать robots.txt через \u003Ccode>colly.NewCollector(colly.RobotsTxt())\u003C\u002Fcode>, но это не заменяет ручную проверку.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Не превышайте разумные лимиты.\u003C\u002Fstrong> 1–5 запросов в секунду на домен — безопасный диапазон. 100+ запросов в секунду — это DoS, не скрейпинг.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>GDPR.\u003C\u002Fstrong> Сбор персональных данных граждан ЕС требует правового основания. Публично доступные деловые данные обычно безопасны, но консультируйтесь с юристом.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>CFAA (США).\u003C\u002Fstrong> Обход технических барьеров защиты может нарушать Computer Fraud and Abuse Act. Не обходьте paywall или аутентификацию без разрешения.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>ProxyHat предоставляет \u003Ca href=\"\u002Fru\u002Flocations\">более 190 локаций\u003C\u002Fa> для гео-таргетинга и поддерживает HTTP, SOCKS5 и sticky-сессии. Ознакомьтесь с \u003Ca href=\"\u002Fru\u002Fpricing\">тарифами\u003C\u002Fa> для выбора подходящего типа прокси.\u003C\u002Fp>\n\n\u003Ch2>Ключевые выводы\u003C\u002Fh2>\n\n\u003Cblockquote>\n\u003Cul>\n\u003Cli>RoundRobinProxySwitcher — простой старт для базовой ротации; SetProxyFunc с кастомной функцией — для продакшна с гео-таргетингом и сессиями.\u003C\u002Fli>\n\u003Cli>Резидентные прокси с динамическим формированием username (\u003Ccode>-country-DE-sid-abc123\u003C\u002Fcode>) — идиоматичный способ ротации в ProxyHat без необходимости управлять пулом URL.\u003C\u002Fli>\n\u003Cli>\u003Ccode>Limit()\u003C\u002Fcode> с \u003Ccode>Parallelism\u003C\u002Fcode>, \u003Ccode>Delay\u003C\u002Fcode> и \u003Ccode>RandomDelay\u003C\u002Fcode> — обязательная настройка для любого продакшн-скрейпера.\u003C\u002Fli>\n\u003Cli>Ретраи через \u003Ccode>c.Clone()\u003C\u002Fcode> в \u003Ccode>OnError\u003C\u002Fcode> — паттерн Colly для обработки временных сбоев.\u003C\u002Fli>\n\u003Cli>Redis-бэкенд позволяет горизонтально масштабировать несколько инстансов Colly с разделяемой очередью.\u003C\u002Fli>\n\u003Cli>Colly не подходит для JS-зависимых SPA — используйте chromedp или Playwright.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fblockquote>\u003Cp>Готовы начать? Изучите \u003Ca href=\"\u002Fru\u002Fpricing\">тарифы ProxyHat\u003C\u002Fa> и \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">документацию\u003C\u002Fa> для быстрой интеграции резидентных прокси в ваш Colly-скрейпер.\u003C\u002Fp>","Ротация прокси в Colly: гайд для Go-разработчиков | ProxyHat","Полное руководство по ротации прокси в Colly: RoundRobinProxySwitcher, SetProxyFunc, резидентные IP, продакшн-паттерны. Примеры кода на Go для высоконагруженного скрейпинга.","\u002Fru\u002Fblog\u002Frotaciya-proksi-v-colly-1",null,"Полное руководство по ротации прокси в Colly: RoundRobinProxySwitcher, SetProxyFunc, резидентные IP, продакшн-паттерны. Примеры кода на Go.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-og.webp",[18,21,24],{"question":19,"answer":20},"Зачем нужна ротация прокси в Colly для скрейпинга?","Ротация прокси предотвращает блокировку IP-адресов целевыми сайтами. Без ротации все запросы идут с одного IP, и антибот-системы (Cloudflare, Akamai) быстро ограничивают доступ — типичный порог 50–200 запросов с одного IP. Ротация резидентных прокси позволяет распределить запросы по множеству реальных IP-адресов, снижая риск блокировок и CAPTCHA до минимума.",{"question":22,"answer":23},"Какой тип прокси лучше всего подходит для ротации в Colly?","Резидентные прокси — оптимальный выбор для сложных целей, так как они используют реальные IP-адреса провайдеров и реже блокируются антибот-системами. Дата-центр прокси подходят для простых задач (открытые API, статичные страницы), но легко детектируются. Мобильные прокси обеспечивают максимальную надёжность для жёстких антибот-систем, но стоят дороже — $20–50\u002FGB против $5–15\u002FGB для резидентных.",{"question":25,"answer":26},"Как избежать блокировок при реализации ротации прокси в Colly?","Используйте резидентные прокси с гео-таргетингом, устанавливайте разумные задержки через \u003Ccode>Limit()\u003C\u002Fcode> (1–5 запросов в секунду на домен), рандомизируйте User-Agent, используйте sticky-сессии для многостраничных потоков и реализуйте ретраи через \u003Ccode>c.Clone()\u003C\u002Fcode> в \u003Ccode>OnError\u003C\u002Fcode>. Уважайте robots.txt и не превышайте разумный лимит запросов. Комбинируйте \u003Ccode>Delay\u003C\u002Fcode> с \u003Ccode>RandomDelay\u003C\u002Fcode> для естественного паттерна трафика.",false,"2026-08-04T10:05:34+00:00","2026-10-03T08:29:56+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-card.webp",12,{"name":35,"slug":36,"bio":37,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[39],{"id":40,"slug":41,"name":42,"description":14,"meta_title":43,"meta_description":44,"parent_id":14},4,"rukovodstva-dlya-razrabotchikov","Руководства для разработчиков","Руководства для разработчиков | Блог ProxyHat","Туториалы по коду и SDK для интеграции прокси в ваши приложения.",[],{"es":47,"ru":13,"ja":48,"pt":49,"pl":50,"ko":51,"tr":52,"zh":53,"it":54,"de":55,"en":56,"fr":57,"x-default":56},"\u002Fes\u002Fblog\u002Frotacion-proxies-colly-golang-1","\u002Fja\u002Fblog\u002Fcolly-purokushi-roteshon-gaido","\u002Fpt\u002Fblog\u002Fproxies-rotativos-em-colly","\u002Fpl\u002Fblog\u002Frotacja-proxy-w-colly-1","\u002Fko\u002Fblog\u002Fcolly-rotating-proxy-guide","\u002Ftr\u002Fblog\u002Fcolly-doner-proxy-rehberi","\u002Fcn\u002Fblog\u002Fcolly-lunhuan-daili-shixian-zhinan","\u002Fit\u002Fblog\u002Fproxy-rotanti-in-colly-guida","\u002Fde\u002Fblog\u002Frotierende-proxies-in-colly","\u002Fblog\u002Frotating-proxies-in-colly-golang","\u002Ffr\u002Fblog\u002Frotation-proxies-colly-golang-1",{"es":47,"ru":13,"ja":48,"pt":49,"pl":50,"ko":51,"tr":52,"zh":53,"it":54,"de":55,"en":56,"fr":57},71,[61,95,122,138],{"id":62,"slug":63,"title":64,"excerpt":65,"featured_image_url":66,"featured_image_alt":67,"card_image_url":68,"og_image_url":69,"published_at":70,"updated_at":71,"content_updated_at":72,"reading_time_minutes":73,"is_featured":27,"indexable":4,"views":74,"author":75,"categories":76,"tags":78},210,"nastrojka-proksi-dlya-ai-agentov","Прокси для AI-агентов: browser-use, Crawl4AI и MCP-сервер","Агенты на облачных виртуалках выходят в сеть с IP дата-центров. Даём актуальную рабочую настройку прокси для browser-use, Crawl4AI и MCP-сервера, таблицу выбора между sticky и ротацией и разбираем ловушки, на которых сгорает бюджет.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-master.webp","Proxy Setup for AI Agents: browser-use, Crawl4AI and an MCP Server","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-og.webp","2026-10-24T09:00:00+00:00","2026-10-24T09:00:20+00:00","2026-10-03T09:41:40+00:00",14,15,{"name":35,"slug":36,"bio":37,"avatar_url":14,"website_url":14,"social_links":14},[77],{"id":40,"slug":41,"name":42,"description":14,"meta_title":43,"meta_description":44,"parent_id":14},[79,83,87,91],{"id":80,"slug":81,"name":82},1,"veb-skraping","Веб-скрапинг",{"id":84,"slug":85,"name":86},2,"rezidentskie-proksi","Резидентские прокси",{"id":88,"slug":89,"name":90},9,"python","Python",{"id":92,"slug":93,"name":94},22,"playwright","Playwright",{"id":96,"slug":97,"title":98,"excerpt":99,"featured_image_url":100,"featured_image_alt":101,"card_image_url":102,"og_image_url":103,"published_at":104,"updated_at":105,"content_updated_at":72,"reading_time_minutes":73,"is_featured":27,"indexable":4,"views":106,"author":107,"categories":108,"tags":110},206,"camoufox-rezidentnye-proksi-python","Camoufox с резидентными прокси: практическое руководство на Python","Как запустить Camoufox — Firefox с патчами на C++ — за резидентными прокси: актуальный Python API, почему geoip нужна sticky-сессия, чек-лист согласованности отпечатка и когда лучше подойдут Patchright или nodriver.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-master.webp","Camoufox with Residential Proxies: A Code-First Python Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-og.webp","2026-10-13T09:00:00+00:00","2026-10-13T09:00:22+00:00",31,{"name":35,"slug":36,"bio":37,"avatar_url":14,"website_url":14,"social_links":14},[109],{"id":40,"slug":41,"name":42,"description":14,"meta_title":43,"meta_description":44,"parent_id":14},[111,112,113,117,118],{"id":80,"slug":81,"name":82},{"id":84,"slug":85,"name":86},{"id":114,"slug":115,"name":116},6,"anti-obnaruzhenie","Анти-обнаружение",{"id":88,"slug":89,"name":90},{"id":119,"slug":120,"name":121},21,"bezgolovnyj-brauzer","Headless-браузер",{"id":123,"slug":124,"title":125,"excerpt":126,"featured_image_url":127,"featured_image_alt":128,"card_image_url":129,"og_image_url":130,"published_at":131,"updated_at":131,"content_updated_at":132,"reading_time_minutes":33,"is_featured":27,"indexable":4,"views":133,"author":134,"categories":135,"tags":137},176,"got-scraping-nodejs-residential-proxies","got-scraping в Node.js: руководство по парсингу с резидентными прокси","Практическое руководство для Node.js-разработчиков: как использовать got-scraping с генератором заголовков, HTTP\u002F2 и резидентными прокси ProxyHat для масштабного парсинга без блокировок.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00",121,{"name":35,"slug":36,"bio":37,"avatar_url":14,"website_url":14,"social_links":14},[136],{"id":40,"slug":41,"name":42,"description":14,"meta_title":43,"meta_description":44,"parent_id":14},[],{"id":139,"slug":140,"title":141,"excerpt":142,"featured_image_url":143,"featured_image_alt":144,"card_image_url":145,"og_image_url":146,"published_at":147,"updated_at":147,"content_updated_at":148,"reading_time_minutes":33,"is_featured":27,"indexable":4,"views":149,"author":150,"categories":151,"tags":153},195,"kak-skrejpit-bybit-v5-market-api","Сбор рыночных данных криптобирж через ротационные прокси: руководство разработчика (на примере Bybit V5 Market API)","Практическое руководство по скрейпингу публичных эндпоинтов Bybit V5 Market API (orderbook, tickers, kline, recent-trade) с ротационными residential-прокси через gate.proxyhat.com. Примеры на Python и Node.js, обработка rate limit, 403-банов и geo-блокировок.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-master.webp","How to Scrape the Bybit V5 Market API with Rotating Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-og.webp","2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00",87,{"name":35,"slug":36,"bio":37,"avatar_url":14,"website_url":14,"social_links":14},[152],{"id":40,"slug":41,"name":42,"description":14,"meta_title":43,"meta_description":44,"parent_id":14},[],[]]