Назад к блогу

Как парсить новостные сайты без блокировок: настройка прокси и обход защиты

Полное руководство по настройке парсинга новостных сайтов: выбор типа прокси, обход антибот-систем, настройка ротации IP и примеры кода на Python.

📅7 марта 2026 г.

Новостные сайты — одни из самых защищённых ресурсов в интернете. Cloudflare, rate limiting, блокировки по IP — всё это делает парсинг новостей серьёзным техническим вызовом. В этом руководстве разберём, как правильно настроить прокси для стабильного сбора данных с новостных порталов, какой тип прокси выбрать для разных задач и как обойти современные системы защиты.

Почему новостные сайты блокируют парсеры

Новостные порталы особенно чувствительны к автоматическому сбору данных по нескольким причинам. Во-первых, контент — это их главный актив, который они монетизируют через рекламу и подписки. Массовый парсинг позволяет конкурентам копировать материалы и снижает уникальную посещаемость. Во-вторых, высокая нагрузка от ботов увеличивает расходы на серверы и CDN.

Современные новостные сайты используют многоуровневую защиту:

  • Cloudflare и аналоги — проверяют JavaScript, TLS-отпечатки браузера, поведенческие паттерны
  • Rate limiting — ограничивают количество запросов с одного IP (обычно 10-50 запросов в минуту)
  • Блокировка по User-Agent — банят стандартные заголовки библиотек (Python-requests, curl)
  • CAPTCHA — показывают при подозрительной активности
  • Геоблокировки — некоторые новостные порталы доступны только из определённых стран

Типичные признаки, по которым новостные сайты детектируют парсеры: одинаковый IP делает много запросов подряд, отсутствие JavaScript, нестандартный порядок HTTP-заголовков, слишком быстрая скорость запросов (человек не может открывать 10 страниц в секунду), отсутствие cookies и referrer.

Важно: Парсинг новостных сайтов находится в серой зоне. Всегда проверяйте robots.txt и Terms of Service целевого ресурса. Для коммерческого использования данных рекомендуется использовать официальные API или заключать партнёрские соглашения.

Какой тип прокси выбрать для парсинга новостей

Выбор типа прокси зависит от масштаба задачи, бюджета и уровня защиты целевых сайтов. Рассмотрим три основных варианта и их применимость для парсинга новостей.

Тип прокси Скорость Стоимость Когда использовать
Прокси дата-центров Высокая (50-100 мс) Низкая Сайты без Cloudflare, большой объём данных, тестирование
Резидентные прокси Средняя (200-500 мс) Высокая Сайты с Cloudflare, строгая защита, геотаргетинг
Мобильные прокси Средняя (300-600 мс) Очень высокая Максимальная защита, мобильные версии новостных сайтов

Прокси дата-центров для парсинга новостей

Подходят для парсинга новостных сайтов без серьёзной защиты: региональные издания, блоги, небольшие информационные порталы. Преимущества: высокая скорость (важно при парсинге сотен источников), низкая стоимость (можно арендовать пул из 50-100 IP), стабильное соединение.

Недостатки: легко детектируются по ASN (принадлежность к дата-центру), часто уже занесены в чёрные списки крупных сайтов, не проходят Cloudflare Challenge в 70% случаев. Используйте прокси дата-центров для массового парсинга RSS-лент, sitemap.xml, API endpoints или для сбора метаданных (заголовки, даты публикации) без загрузки полного контента.

Резидентные прокси — золотой стандарт

Резидентные прокси — это IP-адреса реальных домашних пользователей, предоставленные интернет-провайдерами. Для новостных сайтов они выглядят как обычные посетители, что критически важно при работе с защищёнными ресурсами.

Когда резидентные прокси обязательны: парсинг крупных новостных порталов (CNN, BBC, Reuters, РБК, Коммерсантъ), сайты за Cloudflare или аналогичной защитой, сбор данных из определённых стран (геотаргетинг), длительные сессии с авторизацией. Резидентные прокси проходят JavaScript-проверки Cloudflare, имеют чистую репутацию IP, поддерживают sticky sessions (фиксация IP на 10-30 минут).

Практический совет: используйте резидентные прокси с ротацией по времени (sticky sessions), а не по запросам. Например, один IP работает 10 минут, собирает 20-30 статей, затем меняется. Это выглядит естественнее, чем смена IP на каждый запрос.

Мобильные прокси для особых случаев

Мобильные прокси используют IP мобильных операторов (МТС, Билайн, Tele2). Они имеют максимальное доверие, так как миллионы людей используют мобильный интернет для чтения новостей. Применяйте их для парсинга мобильных версий новостных сайтов (часто имеют упрощённую защиту), сайтов с экстремально строгой защитой, AMP-страниц Google News.

Особенность мобильных прокси: IP часто меняется автоматически (мобильные операторы используют CGNAT), один IP может быть у сотен пользователей одновременно, что делает блокировку бессмысленной. Недостаток — высокая цена, поэтому используйте их точечно, только для самых защищённых целей.

Обход Cloudflare и других антибот-систем

Cloudflare — главный враг парсеров новостных сайтов. Около 40% крупных новостных порталов используют Cloudflare для защиты от ботов. Стандартные библиотеки (requests, urllib) не проходят проверку, так как Cloudflare анализирует TLS-отпечаток, выполнение JavaScript, порядок HTTP-заголовков, поведенческие паттерны.

Стратегии обхода Cloudflare

1. Headless-браузеры (Selenium, Playwright, Puppeteer)

Эмулируют реальный браузер с выполнением JavaScript. Cloudflare видит корректный TLS-отпечаток Chrome/Firefox и пропускает запрос. Минусы: медленно (2-5 секунд на страницу), требует много ресурсов (RAM, CPU).

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# Настройка прокси для Selenium
chrome_options = Options()
chrome_options.add_argument('--proxy-server=http://username:password@proxy.example.com:8080')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(options=chrome_options)
driver.get('https://news-site.com/article')

# Ждём загрузки JavaScript
driver.implicitly_wait(10)
html = driver.page_source
driver.quit()

2. Библиотеки с TLS-fingerprinting (curl_cffi, tls-client)

Имитируют TLS-отпечаток реального браузера без запуска headless-браузера. Работают быстрее Selenium в 10-20 раз, но не выполняют JavaScript. Подходят для сайтов с базовой проверкой Cloudflare (без JS-challenge).

from curl_cffi import requests

proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

response = requests.get(
    'https://news-site.com/article',
    proxies=proxies,
    impersonate='chrome110'  # Имитация TLS-отпечатка Chrome 110
)

print(response.text)

3. Cloudflare-bypass сервисы (scraperapi, scrapingbee)

Платные API, которые автоматически обходят Cloudflare. Вы отправляете URL, они возвращают готовый HTML. Плюсы: не нужно разбираться в технических деталях, автоматическая ротация прокси, обработка CAPTCHA. Минусы: дорого при больших объёмах (от $50/месяц за 100K запросов).

Правильные HTTP-заголовки

Даже с прокси важно отправлять корректные заголовки, иначе сайт вычислит бота по нестандартному User-Agent или отсутствию Accept-Language.

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
    'Accept-Encoding': 'gzip, deflate, br',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Cache-Control': 'max-age=0'
}

Периодически обновляйте User-Agent — используйте актуальные версии браузеров. Проверить свой отпечаток можно на сайтах whoer.net или browserleaks.com.

Настройка ротации IP и управление запросами

Правильная ротация прокси — ключ к стабильному парсингу без блокировок. Новостные сайты отслеживают частоту запросов с одного IP, и превышение лимита приводит к временному или постоянному бану.

Типы ротации прокси

Ротация по запросам — каждый запрос идёт через новый IP. Подходит для быстрого парсинга большого количества разных сайтов, минимизирует риск бана по частоте запросов. Минусы: не подходит для сайтов с сессиями (cookies, авторизация), может выглядеть подозрительно для некоторых защит.

Ротация по времени (sticky sessions) — один IP используется фиксированное время (5-30 минут), затем меняется. Подходит для парсинга одного новостного портала с множеством страниц, сохраняет cookies и сессии, выглядит как поведение реального пользователя. Рекомендуется для большинства задач парсинга новостей.

Ротация по геолокации — смена IP из разных стран/городов. Используется для парсинга геозависимого контента (региональные новости), обхода геоблокировок.

Оптимальная частота запросов

Даже с ротацией прокси нельзя делать запросы слишком часто. Безопасные интервалы для разных типов сайтов:

  • Крупные новостные порталы (РБК, Коммерсантъ, Ведомости) — 2-5 секунд между запросами с одного IP
  • Средние сайты — 1-3 секунды
  • Небольшие блоги и региональные издания — 0.5-1 секунда

Добавляйте случайные задержки (randomization), чтобы паттерн запросов выглядел естественно:

import time
import random

def fetch_article(url, proxies):
    response = requests.get(url, proxies=proxies, headers=headers)
    
    # Случайная задержка от 2 до 5 секунд
    delay = random.uniform(2, 5)
    time.sleep(delay)
    
    return response.text

Пример ротации прокси из пула

Если у вас есть список прокси, можно реализовать простую ротацию вручную:

import itertools
import requests

# Пул прокси
proxy_list = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

# Создаём бесконечный итератор
proxy_pool = itertools.cycle(proxy_list)

def get_next_proxy():
    proxy = next(proxy_pool)
    return {'http': proxy, 'https': proxy}

# Использование
urls = ['https://news1.com/article', 'https://news2.com/article']

for url in urls:
    proxies = get_next_proxy()
    response = requests.get(url, proxies=proxies, headers=headers)
    print(f'Fetched {url} via {proxies["http"]}')

Примеры кода: Python + Scrapy + прокси

Scrapy — профессиональный фреймворк для парсинга, который из коробки поддерживает прокси, middleware, ротацию и обработку ошибок. Рассмотрим полный пример парсера новостного сайта с ротацией прокси.

Установка зависимостей

pip install scrapy scrapy-rotating-proxies

Настройка Scrapy с прокси (settings.py)

# settings.py

# Включаем middleware для ротации прокси
ROTATING_PROXY_LIST = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

DOWNLOADER_MIDDLEWARES = {
    'rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
    'rotating_proxies.middlewares.BanDetectionMiddleware': 620,
}

# Настройки для обхода блокировок
CONCURRENT_REQUESTS = 8  # Не более 8 одновременных запросов
DOWNLOAD_DELAY = 2  # Задержка 2 секунды между запросами
RANDOMIZE_DOWNLOAD_DELAY = True  # Случайная задержка

# User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'

# Повторные попытки при ошибках
RETRY_TIMES = 3
RETRY_HTTP_CODES = [500, 502, 503, 504, 408, 429]

Spider для парсинга новостей

# news_spider.py

import scrapy
from datetime import datetime

class NewsSpider(scrapy.Spider):
    name = 'news_parser'
    
    # Список новостных сайтов для парсинга
    start_urls = [
        'https://example-news.com/latest',
    ]
    
    def parse(self, response):
        # Парсим список статей на главной странице
        articles = response.css('article.news-item')
        
        for article in articles:
            article_url = article.css('a.title::attr(href)').get()
            
            if article_url:
                # Переходим на страницу статьи
                yield response.follow(article_url, callback=self.parse_article)
    
    def parse_article(self, response):
        # Извлекаем данные статьи
        yield {
            'url': response.url,
            'title': response.css('h1.article-title::text').get(),
            'date': response.css('time.published::attr(datetime)').get(),
            'author': response.css('span.author::text').get(),
            'text': ' '.join(response.css('div.article-body p::text').getall()),
            'tags': response.css('a.tag::text').getall(),
            'scraped_at': datetime.now().isoformat(),
        }

Запуск парсера

# Сохранение в JSON
scrapy crawl news_parser -o news_data.json

# Сохранение в CSV
scrapy crawl news_parser -o news_data.csv

Простой парсер на requests + BeautifulSoup

Если не нужна сложная логика, можно использовать связку requests + BeautifulSoup:

import requests
from bs4 import BeautifulSoup
import time
import random

# Настройка прокси
proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

def parse_news_article(url):
    try:
        response = requests.get(url, proxies=proxies, headers=headers, timeout=10)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # Извлечение данных (селекторы зависят от сайта)
        title = soup.find('h1', class_='article-title').text.strip()
        date = soup.find('time', class_='published')['datetime']
        text = ' '.join([p.text for p in soup.find_all('p', class_='article-text')])
        
        return {
            'url': url,
            'title': title,
            'date': date,
            'text': text
        }
    
    except Exception as e:
        print(f'Error parsing {url}: {e}')
        return None

# Парсинг списка статей
urls = [
    'https://news-site.com/article-1',
    'https://news-site.com/article-2',
]

for url in urls:
    article_data = parse_news_article(url)
    if article_data:
        print(article_data)
    
    # Задержка между запросами
    time.sleep(random.uniform(2, 4))

Типичные ошибки при парсинге новостей

Даже с правильной настройкой прокси парсеры часто получают блокировки из-за технических ошибок. Разберём самые частые проблемы и их решения.

Ошибка 1: Слишком высокая частота запросов

Симптомы: HTTP 429 (Too Many Requests), временные баны IP, CAPTCHA. Причина: парсер делает 10-50 запросов в секунду с одного IP. Решение: добавьте задержки (time.sleep()), используйте DOWNLOAD_DELAY в Scrapy, ограничьте CONCURRENT_REQUESTS.

Ошибка 2: Использование одного прокси для всех запросов

Симптомы: прокси быстро банится, даже с задержками. Причина: один IP делает сотни запросов к одному сайту. Решение: используйте пул прокси с ротацией, для крупных сайтов — минимум 10-20 прокси, для sticky sessions меняйте IP каждые 10-15 минут.

Ошибка 3: Игнорирование cookies

Многие новостные сайты устанавливают cookies при первом посещении и проверяют их наличие в последующих запросах. Отсутствие cookies — признак бота. Решение: используйте requests.Session() для автоматического сохранения cookies, в Scrapy включите COOKIES_ENABLED = True.

import requests

session = requests.Session()
session.proxies = {'http': 'http://proxy.com:8080', 'https': 'http://proxy.com:8080'}

# Первый запрос — получаем cookies
response1 = session.get('https://news-site.com')

# Последующие запросы автоматически отправляют cookies
response2 = session.get('https://news-site.com/article')

Ошибка 4: Неправильная обработка редиректов

Новостные сайты часто используют редиректы (301, 302) для мобильных версий, региональных поддоменов, AMP-страниц. Если парсер не следует редиректам, он получает пустую страницу. Решение: в requests включено по умолчанию (allow_redirects=True), проверяйте финальный URL через response.url.

Ошибка 5: Парсинг динамического контента без JavaScript

Многие современные новостные сайты загружают контент через JavaScript (React, Vue). Библиотека requests получает пустой HTML-скелет без статей. Решение: используйте Selenium/Playwright для выполнения JavaScript, проверьте Network в DevTools — возможно, данные загружаются через API (можно парсить напрямую JSON).

Масштабирование: парсинг сотен источников

Когда нужно парсить не один новостной сайт, а сотни источников одновременно (новостные агрегаторы, мониторинг СМИ), требуется масштабируемая архитектура.

Распределённый парсинг с Scrapy Cloud

Scrapy Cloud (от создателей Scrapy) позволяет запускать парсеры в облаке с автоматическим масштабированием. Преимущества: не нужны собственные серверы, автоматическая ротация прокси, мониторинг и логи. Стоимость: от $9/месяц за базовый план.

Очереди задач (Celery + Redis)

Для самостоятельного развёртывания используйте Celery — систему распределённых задач. Архитектура: Redis хранит очередь URL для парсинга, несколько воркеров (серверов) берут задачи из очереди и парсят параллельно, каждый воркер использует свой пул прокси.

# tasks.py

from celery import Celery
import requests

app = Celery('news_parser', broker='redis://localhost:6379/0')

@app.task
def parse_article(url, proxy):
    proxies = {'http': proxy, 'https': proxy}
    response = requests.get(url, proxies=proxies, timeout=10)
    # Парсинг и сохранение данных
    return response.text

# Добавление задач в очередь
urls = ['https://news1.com/article', 'https://news2.com/article']
proxies = ['http://proxy1.com:8080', 'http://proxy2.com:8080']

for url in urls:
    proxy = random.choice(proxies)
    parse_article.delay(url, proxy)  # Асинхронное выполнение

Мониторинг и обработка ошибок

При масштабном парсинге критически важен мониторинг: сколько URL обработано, сколько ошибок, какие прокси забанены. Используйте Sentry для отслеживания ошибок Python, Grafana + Prometheus для метрик (запросов в секунду, время ответа), логирование в ELK Stack (Elasticsearch, Logstash, Kibana).

Совет: Создайте систему автоматической проверки прокси. Каждые 5-10 минут отправляйте тестовый запрос через каждый прокси на whoer.net или httpbin.org. Если прокси не отвечает или забанен — исключайте его из пула и добавляйте новый.

Оптимизация расходов на прокси

При парсинге сотен источников расходы на прокси могут достигать тысяч долларов в месяц. Стратегии оптимизации: используйте прокси дата-центров для простых сайтов (RSS, API), резидентные — только для защищённых, кешируйте данные — не парсите одну и ту же статью дважды, парсите в непиковые часы (ночью нагрузка на сайты ниже, меньше риск бана).

Пример: для парсинга 500 новостных сайтов можно использовать 80% прокси дата-центров (для RSS и простых сайтов) и 20% резидентных (для топ-100 защищённых порталов). Это снизит расходы в 3-5 раз.

Заключение

Парсинг новостных сайтов — технически сложная задача, требующая правильного выбора прокси, настройки ротации и обхода антибот-систем. Ключевые выводы из статьи: для защищённых новостных порталов (Cloudflare, строгий rate limiting) используйте резидентные прокси с sticky sessions, для массового парсинга сотен источников подходят прокси дата-центров с быстрой ротацией, обязательно добавляйте задержки между запросами (2-5 секунд) и корректные HTTP-заголовки, для обхода Cloudflare применяйте headless-браузеры (Selenium, Playwright) или библиотеки с TLS-fingerprinting.

При масштабировании используйте распределённые системы (Celery, Scrapy Cloud) и мониторинг ошибок. Помните, что парсинг должен быть этичным — соблюдайте robots.txt, не создавайте чрезмерную нагрузку на серверы и уважайте авторские права на контент.

Если вы планируете парсить крупные новостные порталы с защитой Cloudflare, рекомендуем использовать резидентные прокси — они обеспечивают высокий уровень доверия и минимальный риск блокировок. Для задач, где важна скорость и объём данных (парсинг RSS, API endpoints), подойдут прокси дата-центров.