Skip to content
Intermediate / 1 min read

Как настроить датацентровые прокси Smartproxy на Linux для мониторинга цен на Python

Направляйте запланированные запросы мониторинга цен на Python через датацентровые прокси Smartproxy на Linux, сохраняя учетные данные вне кода, с повторными попытками и задержками, рекомендациями по ротации, журналированием в CSV и расписанием cron.

Linux SOCKS5 HTTP(S) Веб-скрейпинг

Обзор

Smartproxy — это дружелюбная для новичков прокси-сеть с пулами резидентных и датацентровых прокси, доступными по HTTP и SOCKS5, с оплатой по фиксированной месячной модели. В этом руководстве мы направим ее датацентровый пул на конкретную, распространенную задачу на Linux: запланированный мониторинг цен на Python.

Мониторинг цен хорошо подходит для датацентровых IP. Запросы быстрые, цели — публичные страницы товаров, а нагрузка в основном на чтение. Если конкретный ритейлер начнет блокировать диапазоны дата-центров, тот же скрипт можно запустить через пул резидентных прокси — изменятся только конечная точка и учетные данные.

К концу у вас будет:

  • Учетные данные, хранящиеся вне исходного кода
  • Запрос через прокси, проверенный из командной строки
  • Скрипт на Python, который получает страницы товаров через прокси с повторными попытками и задержками
  • Цены, добавляемые в CSV-файл с временными метками
  • Запись в cron, которая запускает задачу по расписанию

Вам не нужен графический интерфейс для всего этого. Smartproxy также предлагает расширения для браузера, но для headless-задачи на Linux нужны только хост, порт, имя пользователя и пароль из вашей панели управления.

Предварительные требования

  • Linux-хост — приведенные ниже команды работают в семействах Debian/Ubuntu и Fedora/RHEL
  • Python 3.9 или новее
  • Аккаунт Smartproxy с доступом к датацентровым прокси
  • Хост, порт, имя пользователя и пароль прокси, указанные в вашей панели управления Smartproxy

Датацентровые или резидентные?

Оба типа пулов настраиваются в коде одинаково, поэтому решение зависит от целевого сайта, а не от инструментов.

Фактор Датацентровые Резидентные
Скорость на запрос Высокая Средняя
Стоимость за ГБ Ниже Выше
Риск блокировки на крупных ритейлерах Выше Ниже
Лучшее применение Высокообъемное чтение терпимых сайтов Защищенные сайты и гео-точное ценообразование

Практические правила:

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

Шаги

Шаг 1 — Экспортируйте учетные данные и проверьте конечную точку

Установите четыре значения из вашей панели управления как переменные окружения для текущей сессии оболочки. Замените заполнители своими значениями.

export SMART_HOST="<host-from-dashboard>"
export SMART_PORT="<port-from-dashboard>"
export SMART_USER="<username>"
export SMART_PASS="<password>"

Выполните один запрос через прокси. Передача учетных данных с -U позволяет избежать проблем со специальными символами в пароле.

curl -sS --max-time 20 -x "http://${SMART_HOST}:${SMART_PORT}" -U "${SMART_USER}:${SMART_PASS}" https://api.ipify.org

Ответом должен быть IP-адрес, не являющийся IP-адресом вашего сервера. Если вместо этого вы видите ошибку 407, перейдите к таблице устранения неполадок в конце.

Шаг 2 — Создайте проект и переместите секреты в файл

  1. Создайте каталог и виртуальное окружение.
  2. Установите requests и python-dotenv, который загружает файл .env в окружение во время выполнения.
mkdir -p ~/price-monitor && cd ~/price-monitor
python3 -m venv .venv && source .venv/bin/activate
pip install requests python-dotenv

Создайте файл секретов и ограничьте его права доступа. Этот файл никогда не должен попадать в репозиторий.

# ~/price-monitor/.env
SMART_HOST=<host-from-dashboard>
SMART_PORT=<port-from-dashboard>
SMART_USER=<username>
SMART_PASS=<password>
chmod 600 .env
cat > .gitignore <<'EOF'
.env
.venv/
EOF

Шаг 3 — Создайте URL прокси в Python

Создайте URL один раз и повторно используйте его. Экранирование имени пользователя и пароля с помощью quote() защищает от символов, таких как @, : или #, которые иначе нарушили бы разбор URL.

# ~/price-monitor/proxy_config.py
import os
from urllib.parse import quote
from dotenv import load_dotenv

load_dotenv()

def proxy_url(scheme='http'):
    user = quote(os.environ['SMART_USER'], safe='')
    password = quote(os.environ['SMART_PASS'], safe='')
    host = os.environ['SMART_HOST']
    port = os.environ['SMART_PORT']
    return f'{scheme}://{user}:{password}@{host}:{port}'

PROXIES = {'http': proxy_url(), 'https': proxy_url()}

Если ваша конечная точка использует другой порт для HTTPS-трафика, задайте оба ключа отдельно, а не предполагайте, что порт общий.

Шаг 4 — Получите страницу через прокси с повторными попытками

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

# ~/price-monitor/fetch_price.py
import time
import requests
from proxy_config import PROXIES

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
                  '(KHTML, like Gecko) Chrome/124.0 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.9',
}

def fetch(url, retries=3, timeout=25):
    last_error = None
    for attempt in range(1, retries + 1):
        try:
            response = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=timeout)
            if response.status_code == 200:
                return response.text
            last_error = 'HTTP %s' % response.status_code
        except requests.RequestException as exc:
            last_error = str(exc)
        time.sleep(2 ** attempt)
    raise RuntimeError('Failed to fetch %s: %s' % (url, last_error))

if __name__ == '__main__':
    html = fetch('https://example.com/product/123')
    print(html[:500])

Шаг 5 — Извлеките цену и добавьте ее в CSV

HTML-парсеры, такие как BeautifulSoup или selectolax, обеспечивают более устойчивое извлечение, но регулярного выражения достаточно, чтобы проверить конвейер, прежде чем вкладываться в селекторы.

# ~/price-monitor/parse_price.py
import csv
import datetime
import re
import sys
from fetch_price import fetch

def parse_price(html):
    # Замените этот шаблон на селектор, соответствующий разметке целевого сайта.
    match = re.search(r'data-price=([0-9.]+)', html)
    return float(match.group(1)) if match else None

def main(url):
    price = parse_price(fetch(url))
    with open('prices.csv', 'a', newline='', encoding='utf-8') as handle:
        writer = csv.writer(handle)
        writer.writerow([datetime.datetime.now(datetime.UTC).isoformat(), url, price])

if __name__ == '__main__':
    main(sys.argv[1] if len(sys.argv) > 1 else 'https://example.com/product/123')

Шаг 6 — Решите, как должна работать ротация для вашей конечной точки

Поведение ротации зависит от предоставленной вам конечной точки, поэтому проверьте панель управления, прежде чем что-то предполагать:

  • Если порт меняет исходящий IP при каждом запросе, достаточно просто снова вызвать fetch() — каждое новое соединение может выходить с другого IP.
  • Если порт удерживает закрепленную сессию, перебирайте порты, указанные в вашей панели управления, и закрепляйте один порт за каждым рабочим потоком.
  • Повторно используйте один и тот же requests.Session() только тогда, когда вам нужна закрепленная сессия; новая сессия для каждого запроса — более безопасный вариант по умолчанию для мониторинга.

Чтобы убедиться в ротации, запросите конечную точку IP несколько раз подряд.

def check_ip():
    return fetch('https://api.ipify.org').strip()

if __name__ == '__main__':
    for _ in range(5):
        print(check_ip())

Шаг 7 — Добавьте умеренную параллельность

Пул потоков сокращает длинный список URL, но параллельность также является самым быстрым способом получить блокировку. Начните с малого и увеличивайте количество рабочих потоков только при стабильном уровне ошибок.

Количество параллельных потоков Когда это разумно
1–3 Первый запуск против новой цели
4–6 Стабильный запуск с датацентровыми прокси, нет ответов с ограничением скорости
8 и более Только после тестирования, и обычно с резидентными IP
from concurrent.futures import ThreadPoolExecutor, as_completed
from fetch_price import fetch

urls = [f'https://example.com/product/{sku}' for sku in range(1, 6)]

with ThreadPoolExecutor(max_workers=5) as pool:
    futures = {pool.submit(fetch, url): url for url in urls}
    for future in as_completed(futures):
        url = futures[future]
        try:
            print(url, len(future.result()))
        except Exception as exc:
            print(url, 'failed:', exc)

Шаг 8 — Запланируйте задачу с помощью cron

Отредактируйте crontab и добавьте одну строку. cd важен, потому что скрипт полагается на то, что его файл .env находится в рабочем каталоге.

crontab -e
0 */6 * * * cd /home/<user>/price-monitor && .venv/bin/python parse_price.py https://example.com/product/123 >> run.log 2>&1

Используйте абсолютный путь к Python виртуального окружения. Простой python в cron часто указывает на системный интерпретатор и не увидит установленные вами пакеты.

Использование SOCKS5 вместо HTTP

Smartproxy поддерживает SOCKS5 наряду с HTTP, и переключение — это изменение одной строки. Подтвердите порт SOCKS5 в вашей панели управления, так как он может отличаться от порта HTTP.

pip install 'requests[socks]'
PROXIES = {'http': proxy_url('socks5'), 'https': proxy_url('socks5')}

SOCKS5 полезен, когда вы также хотите, чтобы разрешение DNS проходило через прокси, или когда другой инструмент в вашем конвейере поддерживает только SOCKS5.

Устранение неполадок

Симптом Вероятная причина Что попробовать
407 Proxy Authentication Required Неверные или устаревшие учетные данные, или пароль с неэкранированными специальными символами Скопируйте значения из панели управления заново, проверьте с помощью команды curl -U из шага 1 и полагайтесь на quote() в Python
403 или страница CAPTCHA Цель блокирует диапазоны дата-центров, или заголовки выглядят автоматизированными Замедлите выполнение, отправляйте реалистичные заголовки браузера и перенесите эту цель на пул резидентных прокси
429 Too Many Requests Слишком много параллельных потоков Уменьшите max_workers, сохраните экспоненциальную задержку и добавьте паузу между пакетами
Тайм-аут соединения при каждом запросе Неверный хост или порт, или исходящий трафик на этом порту заблокирован Повторно запустите проверку curl; проверьте ufw, iptables или любую корпоративную политику выхода для порта прокси
Работает с IP-чекером, но не работает на цели Антибот-защита, специфичная для этого сайта Протестируйте один запрос в обычной сессии браузера, настройте заголовки и ожидайте, что некоторым целям потребуются резидентные IP
CERTIFICATE_VERIFY_FAILED Устаревший пакет CA на хосте Обновите ca-certificates и пакеты виртуального окружения, а не отключайте проверку

Итоги

  • Датацентровый пул Smartproxy — это практичный выбор по умолчанию для высокообъемного мониторинга цен только для чтения на Linux.
  • Храните хост, порт, имя пользователя и пароль в файле .env с правами 600 и загружайте их с помощью python-dotenv.
  • Экранируйте учетные данные перед вставкой в URL прокси, иначе специальные символы нарушат разбор.
  • Всегда устанавливайте тайм-аут запроса, повторяйте с задержкой и сохраняйте низкую параллельность, пока уровень ошибок не докажет, что увеличение безопасно.
  • Проверьте панель управления, чтобы узнать, меняет ли ваша конечная точка IP при каждом запросе или удерживает закрепленную сессию, и проектируйте запуск соответственно.
  • Переключите одну заблокированную цель на пул резидентных прокси вместо перестройки всей задачи и используйте SOCKS5 только тогда, когда он нужен для DNS или по причинам инструментария.