Как настроить датацентровые прокси Smartproxy на Linux для мониторинга цен на Python
Направляйте запланированные запросы мониторинга цен на Python через датацентровые прокси Smartproxy на Linux, сохраняя учетные данные вне кода, с повторными попытками и задержками, рекомендациями по ротации, журналированием в CSV и расписанием cron.
Обзор
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 — Создайте проект и переместите секреты в файл
- Создайте каталог и виртуальное окружение.
- Установите
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 или по причинам инструментария.