Comment configurer les proxys datacenter Smartproxy sous Linux pour la surveillance des prix en Python
Acheminez les requêtes planifiées de surveillance des prix en Python via les proxys datacenter Smartproxy sous Linux, avec des identifiants conservés hors de votre code, des tentatives et un backoff, des conseils de rotation, une journalisation CSV et une planification cron.
Aperçu
Smartproxy est un réseau de proxys adapté aux débutants avec des pools résidentiels et datacenter accessibles via HTTP et SOCKS5, facturé selon un modèle mensuel fixe. Ce tutoriel oriente son pool datacenter vers une tâche concrète et courante sous Linux : la surveillance planifiée des prix en Python.
La surveillance des prix convient bien aux IP datacenter. Les requêtes sont rapides, les cibles sont des pages produit publiques et la charge de travail est à forte lecture. Si un détaillant particulier commence à bloquer les plages datacenter, le même script s'exécute contre le pool résidentiel — seuls le point de terminaison et les identifiants changent.
À la fin, vous disposerez de :
- Identifiants stockés en dehors de votre code source
- Une requête proxy vérifiée depuis la ligne de commande
- Un script Python qui récupère les pages produit via le proxy avec tentatives et backoff
- Des prix ajoutés à un fichier CSV avec horodatages
- Une entrée cron qui exécute la tâche selon un calendrier
Vous n'avez pas besoin d'une interface graphique pour tout cela. Smartproxy propose également des extensions de navigateur, mais une tâche Linux sans interface n'a besoin que de l'hôte, du port, du nom d'utilisateur et du mot de passe de votre tableau de bord.
Prérequis
- Un hôte Linux — les commandes ci-dessous fonctionnent sur les familles Debian/Ubuntu et Fedora/RHEL
- Python 3.9 ou plus récent
- Un compte Smartproxy avec accès aux proxys datacenter
- L'hôte, le port, le nom d'utilisateur et le mot de passe du proxy indiqués dans votre tableau de bord Smartproxy
Datacenter ou résidentiel ?
Les deux types de pools sont configurés de manière identique dans le code, donc la décision concerne le site cible, pas l'outillage.
| Facteur | Datacenter | Résidentiel |
|---|---|---|
| Vitesse par requête | Rapide | Modérée |
| Coût par Go | Inférieur | Supérieur |
| Risque de blocage chez les grands détaillants | Plus élevé | Plus faible |
| Idéal pour | Lectures à haut volume de sites tolérants | Sites protégés et tarification géolocalisée précise |
Règles empiriques :
- Commencez par le datacenter, car c'est la façon la moins chère et la plus rapide de prouver que votre parseur fonctionne.
- Déplacez une seule cible récalcitrante vers le résidentiel plutôt que de migrer toute la tâche.
- Gardez le schéma de proxy et l'authentification identiques entre les pools afin que le changement soit une modification de configuration, pas une réécriture.
Étapes
Étape 1 — Exportez vos identifiants et vérifiez le point de terminaison
Définissez les quatre valeurs de votre tableau de bord comme variables d'environnement pour la session shell actuelle. Remplacez les espaces réservés par vos propres valeurs.
export SMART_HOST="<host-from-dashboard>"
export SMART_PORT="<port-from-dashboard>"
export SMART_USER="<username>"
export SMART_PASS="<password>"
Exécutez une seule requête via le proxy. Passer les identifiants avec -U évite les problèmes liés aux caractères spéciaux dans le mot de passe.
curl -sS --max-time 20 -x "http://${SMART_HOST}:${SMART_PORT}" -U "${SMART_USER}:${SMART_PASS}" https://api.ipify.org
La réponse doit être une adresse IP qui n'est pas l'IP de votre propre serveur. Si vous voyez plutôt une erreur 407, passez au tableau de dépannage à la fin.
Étape 2 — Créez le projet et déplacez les secrets dans un fichier
- Créez un répertoire et un environnement virtuel.
- Installez
requestsainsi quepython-dotenv, qui charge le fichier.envdans l'environnement à l'exécution.
mkdir -p ~/price-monitor && cd ~/price-monitor
python3 -m venv .venv && source .venv/bin/activate
pip install requests python-dotenv
Créez le fichier de secrets et verrouillez ses permissions. Ce fichier ne doit jamais être commité.
# ~/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
Étape 3 — Construisez l'URL du proxy en Python
Construisez l'URL une fois et réutilisez-la. Encoder le nom d'utilisateur et le mot de passe avec quote() protège contre les caractères tels que @, : ou # qui casseraient sinon l'analyse de l'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()}
Si votre point de terminaison utilise un port différent pour le trafic HTTPS, définissez les deux clés séparément plutôt que de supposer que le port est partagé.
Étape 4 — Récupérez une page via le proxy avec tentatives
Enveloppez la requête dans une petite boucle de tentatives. Le backoff exponentiel vous évite de marteler une cible qui vous limite en débit.
# ~/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])
Étape 5 — Extrayez le prix et ajoutez-le au CSV
Les parseurs HTML tels que BeautifulSoup ou selectolax offrent une extraction plus robuste, mais une regex suffit pour valider le pipeline avant d'investir dans des sélecteurs.
# ~/price-monitor/parse_price.py
import csv
import datetime
import re
import sys
from fetch_price import fetch
def parse_price(html):
# Remplacez ce motif par un sélecteur qui correspond au balisage du site cible.
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')
Étape 6 — Décidez comment la rotation doit fonctionner pour votre point de terminaison
Le comportement de rotation dépend du point de terminaison qui vous a été attribué, donc vérifiez votre tableau de bord avant de supposer quoi que ce soit :
- Si le port fait tourner l'IP de sortie à chaque requête, il suffit simplement d'appeler à nouveau
fetch()— chaque nouvelle connexion peut sortir depuis une IP différente. - Si le port maintient une session persistante, alternez entre les ports listés dans votre tableau de bord et gardez un port par worker.
- Ne continuez à réutiliser la même
requests.Session()que lorsque vous voulez une session persistante ; une nouvelle session par requête est la valeur par défaut plus sûre pour la surveillance.
Pour confirmer la rotation, demandez le point de terminaison d'IP plusieurs fois de suite.
def check_ip():
return fetch('https://api.ipify.org').strip()
if __name__ == '__main__':
for _ in range(5):
print(check_ip())
Étape 7 — Ajoutez une concurrence modérée
Un pool de threads raccourcit une longue liste d'URL, mais la concurrence est aussi le moyen le plus rapide de se faire bloquer. Commencez petit et n'augmentez le nombre de workers que tant que les taux d'erreur restent stables.
| Workers simultanés | Quand c'est raisonnable |
|---|---|
| 1 à 3 | Premier lancement contre une nouvelle cible |
| 4 à 6 | Exécution datacenter stable, aucune réponse de limitation de débit |
| 8 ou plus | Uniquement après tests, et généralement avec des IP résidentielles |
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)
Étape 8 — Planifiez la tâche avec cron
Modifiez votre crontab et ajoutez une ligne. Le cd est important car le script dépend de la présence de son fichier .env dans le répertoire de travail.
crontab -e
0 */6 * * * cd /home/<user>/price-monitor && .venv/bin/python parse_price.py https://example.com/product/123 >> run.log 2>&1
Utilisez le chemin absolu vers le Python de l'environnement virtuel. Un simple python sous cron se résout souvent vers l'interpréteur système et ne verra pas vos packages installés.
Utiliser SOCKS5 au lieu de HTTP
Smartproxy prend en charge SOCKS5 aux côtés de HTTP, et le changement se fait sur une ligne. Confirmez le port SOCKS5 dans votre tableau de bord, car il peut différer du port HTTP.
pip install 'requests[socks]'
PROXIES = {'http': proxy_url('socks5'), 'https': proxy_url('socks5')}
SOCKS5 est utile lorsque vous souhaitez aussi que la résolution DNS passe par le proxy, ou lorsqu'un autre outil de votre pipeline ne parle que SOCKS5.
Dépannage
| Symptôme | Cause probable | Quoi essayer |
|---|---|---|
407 Proxy Authentication Required |
Identifiants erronés ou obsolètes, ou mot de passe avec des caractères spéciaux non échappés | Recopiez les valeurs depuis le tableau de bord, vérifiez avec la commande curl -U de l'étape 1 et fiez-vous à quote() en Python |
403 ou une page CAPTCHA |
La cible bloque les plages datacenter, ou les en-têtes semblent automatisés | Ralentissez l'exécution, envoyez des en-têtes de navigateur réalistes et déplacez cette cible vers le pool résidentiel |
429 Too Many Requests |
Trop de workers simultanés | Réduisez max_workers, conservez le backoff exponentiel et ajoutez une pause entre les lots |
| Délai de connexion à chaque requête | Hôte ou port incorrect, ou trafic sortant sur ce port bloqué | Relancez la vérification curl ; examinez ufw, iptables ou toute politique de sortie d'entreprise pour le port proxy |
| Fonctionne avec un vérificateur d'IP mais échoue sur la cible | Protection anti-bot spécifique à ce site | Testez une requête dans une session de navigateur normale, ajustez les en-têtes et attendez-vous à ce que certaines cibles nécessitent des IP résidentielles |
CERTIFICATE_VERIFY_FAILED |
Bundle de CA obsolète sur l'hôte | Mettez à jour ca-certificates et les packages de l'environnement virtuel plutôt que de désactiver la vérification |
Résumé
- Le pool datacenter de Smartproxy est une valeur par défaut pratique pour la surveillance des prix en lecture seule à haut volume sous Linux.
- Conservez l'hôte, le port, le nom d'utilisateur et le mot de passe dans un fichier
.envavec des permissions600, et chargez-les avecpython-dotenv. - Encodez les identifiants avant de les mettre dans une URL de proxy, sinon les caractères spéciaux casseront l'analyse.
- Définissez toujours un délai d'attente pour les requêtes, réessayez avec backoff et maintenez une concurrence faible jusqu'à ce que les taux d'erreur prouvent qu'il est sûr de l'augmenter.
- Vérifiez votre tableau de bord pour savoir si votre point de terminaison effectue une rotation à chaque requête ou maintient une session persistante, puis concevez l'exécution en conséquence.
- Basculez une seule cible bloquée vers le pool résidentiel au lieu de reconstruire la tâche, et n'utilisez SOCKS5 que lorsque vous en avez besoin pour des raisons de DNS ou d'outillage.