
Dans un monde où l’efficacité numérique est cruciale, l’automatisation des tâches web répétitives devient un atout majeur. Python, avec sa bibliothèque Selenium, offre une solution puissante pour créer des bots intelligents capables d’interagir avec n’importe quel site web comme le ferait un utilisateur humain.
Que vous souhaitiez automatiser la collecte de données, tester des applications web, ou simplifier des processus administratifs, ce guide vous accompagnera pas à pas dans la création de votre premier bot web
Qu’est-ce que Selenium ?
Selenium est une suite d’outils open-source permettant d’automatiser les navigateurs web. Initialement conçu pour les tests automatisés, Selenium est devenu l’outil de référence pour l’automatisation web grâce à ses capacités :
- Multi-navigateurs : Compatible avec Chrome, Firefox, Safari, Edge
- Multi-plateformes : Fonctionne sur Windows, macOS, Linux
- Multi-langages : Support de Python, Java, C#, JavaScript, Ruby
- Interaction complète : Simulation de clics, saisie de texte, navigation
Installation et configuration
Prérequis
Avant de commencer, assurez-vous d’avoir :
- Python 3.7 ou version supérieure
- Un navigateur web (Chrome recommandé)
- Une connexion internet stable
Installation de Selenium

Installation du WebDriver
Le WebDriver est le pont entre votre code Python et le navigateur. Pour Chrome :

Cette approche moderne télécharge automatiquement la version compatible du driver Chrome.
Votre premier bot Selenium
Commençons par créer un script simple qui ouvre un navigateur et navigue vers un site web :
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import time
class WebBot:
def __init__(self):
# Configuration du driver Chrome
options = webdriver.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
# Initialisation du driver
service = Service(ChromeDriverManager().install())
self.driver = webdriver.Chrome(service=service, options=options)
self.wait = WebDriverWait(self.driver, 10)
def open_website(self, url):
"""Ouvre un site web"""
self.driver.get(url)
print(f"Page ouverte : {url}")
def close(self):
"""Ferme le navigateur"""
self.driver.quit()
# Utilisation
bot = WebBot()
bot.open_website("https://www.google.com")
time.sleep(3)
bot.close()
Recherche et interaction avec les éléments
Pour interagir avec une page web, vous devez localiser les éléments HTML. Selenium offre plusieurs méthodes :
def find_elements_demo(self):
# Par ID
element = self.driver.find_element(By.ID, "search-box")
# Par nom de classe
elements = self.driver.find_elements(By.CLASS_NAME, "button")
# Par nom d'attribut
element = self.driver.find_element(By.NAME, "username")
# Par sélecteur CSS
element = self.driver.find_element(By.CSS_SELECTOR, ".login-form input[type='password']")
# Par XPath
element = self.driver.find_element(By.XPATH, "//button[@class='submit-btn']")
# Par texte de lien
element = self.driver.find_element(By.LINK_TEXT, "Connexion")
Cas d’usage pratiques
1. Bot de recherche automatisée
Créons un bot qui effectue des recherches automatiques sur Google :
python
class GoogleSearchBot(WebBot):
def search(self, query):
"""Effectue une recherche sur Google"""
try:
# Ouvrir Google
self.open_website("https://www.google.com")
# Accepter les cookies si nécessaire
try:
accept_btn = self.wait.until(
EC.element_to_be_clickable((By.ID, "L2AGLb"))
)
accept_btn.click()
except:
pass # Pas de popup de cookies
# Localiser la barre de recherche
search_box = self.wait.until(
EC.presence_of_element_located((By.NAME, "q"))
)
# Saisir la requête
search_box.clear()
search_box.send_keys(query)
search_box.submit()
# Attendre les résultats
self.wait.until(
EC.presence_of_element_located((By.ID, "search"))
)
# Extraire les titres des résultats
results = self.driver.find_elements(By.CSS_SELECTOR, "h3")
print(f"Résultats pour '{query}':")
for i, result in enumerate(results[:5], 1):
print(f"{i}. {result.text}")
except Exception as e:
print(f"Erreur lors de la recherche : {e}")
# Utilisation
search_bot = GoogleSearchBot()
search_bot.search("Python Selenium automation")
time.sleep(5)
search_bot.close()
2. Bot de connexion automatique
Automatisons la connexion à un site web :
python
class LoginBot(WebBot):
def login(self, url, username, password, username_selector, password_selector, login_btn_selector):
"""Connexion automatique à un site"""
try:
# Ouvrir la page de connexion
self.open_website(url)
# Attendre que la page se charge
username_field = self.wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, username_selector))
)
# Saisir les identifiants
username_field.clear()
username_field.send_keys(username)
password_field = self.driver.find_element(By.CSS_SELECTOR, password_selector)
password_field.clear()
password_field.send_keys(password)
# Cliquer sur le bouton de connexion
login_btn = self.driver.find_element(By.CSS_SELECTOR, login_btn_selector)
login_btn.click()
# Attendre la redirection
time.sleep(3)
print(f"Connexion réussie sur {url}")
except Exception as e:
print(f"Erreur de connexion : {e}")
3. Bot de surveillance de prix
Créons un bot qui surveille les prix sur un site e-commerce :
python
class PriceMonitorBot(WebBot):
def __init__(self):
super().__init__()
self.prices_history = []
def monitor_price(self, product_url, price_selector, target_price=None):
"""Surveille le prix d'un produit"""
try:
self.open_website(product_url)
# Attendre que le prix se charge
price_element = self.wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, price_selector))
)
# Extraire le prix
price_text = price_element.text
# Nettoyer le texte pour extraire le nombre
import re
price_match = re.search(r'[\d,]+\.?\d*', price_text.replace(',', ''))
if price_match:
current_price = float(price_match.group().replace(',', ''))
self.prices_history.append({
'price': current_price,
'timestamp': time.time()
})
print(f"Prix actuel : {current_price}€")
if target_price and current_price <= target_price:
self.send_alert(f"🎉 Prix cible atteint ! {current_price}€ <= {target_price}€")
return current_price
except Exception as e:
print(f"Erreur de surveillance : {e}")
return None
def send_alert(self, message):
"""Envoie une alerte (à personnaliser)"""
print(f"ALERTE : {message}")
# Ici vous pourriez ajouter l'envoi d'email, notification, etc.
Techniques avancées
Gestion des attentes intelligentes
Utilisez les attentes explicites pour rendre vos bots plus fiables :
python
from selenium.webdriver.support import expected_conditions as EC
class AdvancedBot(WebBot):
def wait_for_element(self, locator, timeout=10):
"""Attendre qu'un élément soit présent"""
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located(locator)
)
def wait_for_clickable(self, locator, timeout=10):
"""Attendre qu'un élément soit cliquable"""
return WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable(locator)
)
def wait_for_text(self, locator, text, timeout=10):
"""Attendre qu'un élément contienne un texte spécifique"""
return WebDriverWait(self.driver, timeout).until(
EC.text_to_be_present_in_element(locator, text)
)
Mode headless (sans interface)
Pour des bots en production, le mode headless améliore les performances :
python
def setup_headless_driver(self):
"""Configuration pour mode headless"""
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
service = Service(ChromeDriverManager().install())
return webdriver.Chrome(service=service, options=options)
Gestion des cookies et sessions
python
def manage_cookies(self):
"""Gestion des cookies"""
# Sauvegarder les cookies
cookies = self.driver.get_cookies()
# Ajouter un cookie personnalisé
self.driver.add_cookie({
'name': 'session_id',
'value': 'abc123',
'domain': 'example.com'
})
# Supprimer tous les cookies
self.driver.delete_all_cookies()
Bonnes pratiques et optimisation
1. Respect des sites web
python
class EthicalBot(WebBot):
def __init__(self, delay_between_requests=2):
super().__init__()
self.delay = delay_between_requests
def polite_request(self, action):
"""Exécute une action avec délai respectueux"""
result = action()
time.sleep(self.delay) # Respecter le serveur
return result
def check_robots_txt(self, domain):
"""Vérifier robots.txt (implémentation basique)"""
import requests
try:
response = requests.get(f"https://{domain}/robots.txt")
return "User-agent: *" in response.text
except:
return True # Autoriser par défaut
2. Gestion des erreurs robuste
python
def robust_element_interaction(self, locator, action="click", max_retries=3):
"""Interaction robuste avec gestion d'erreurs"""
for attempt in range(max_retries):
try:
element = self.wait.until(EC.element_to_be_clickable(locator))
if action == "click":
element.click()
elif action == "text":
return element.text
elif action == "send_keys":
return element # Retourner pour saisie ultérieure
return True
except Exception as e:
print(f"Tentative {attempt + 1} échouée : {e}")
if attempt == max_retries - 1:
raise e
time.sleep(2) # Attendre avant de réessayer
3. Logging et monitoring
python
import logging
from datetime import datetime
class MonitoredBot(WebBot):
def __init__(self):
super().__init__()
self.setup_logging()
def setup_logging(self):
"""Configuration du logging"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('bot.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def log_action(self, action, success=True, details=""):
"""Logger les actions du bot"""
status = "SUCCESS" if success else "FAILED"
self.logger.info(f"{action} - {status} - {details}")
Déploiement et automatisation
Planification avec cron (Linux/Mac)
bash
# Exécuter le bot chaque jour à 9h
0 9 * * * /usr/bin/python3 /path/to/your/bot.py
# Exécuter toutes les heures
0 * * * * /usr/bin/python3 /path/to/your/bot.py
Planification avec Task Scheduler (Windows)
python
# Script pour Windows Task Scheduler
import subprocess
import sys
def run_bot():
try:
# Votre code de bot ici
bot = YourBot()
bot.run()
bot.close()
print("Bot exécuté avec succès")
return 0
except Exception as e:
print(f"Erreur : {e}")
return 1
if __name__ == "__main__":
sys.exit(run_bot())
Exemple complet : Bot de veille concurrentielle
Voici un exemple complet qui combine plusieurs techniques :
python
import json
from datetime import datetime
import smtplib
from email.mime.text import MIMEText
class CompetitorMonitorBot(WebBot):
def __init__(self, config_file="config.json"):
super().__init__()
self.load_config(config_file)
self.results = []
def load_config(self, config_file):
"""Charger la configuration depuis un fichier JSON"""
with open(config_file, 'r') as f:
self.config = json.load(f)
def monitor_competitors(self):
"""Surveiller les concurrents"""
for competitor in self.config['competitors']:
try:
print(f"Surveillance de {competitor['name']}...")
# Naviguer vers le site
self.open_website(competitor['url'])
# Extraire les informations
data = self.extract_competitor_data(competitor)
# Sauvegarder les résultats
self.results.append({
'competitor': competitor['name'],
'data': data,
'timestamp': datetime.now().isoformat()
})
time.sleep(self.config.get('delay_between_sites', 5))
except Exception as e:
print(f"Erreur pour {competitor['name']}: {e}")
def extract_competitor_data(self, competitor):
"""Extraire les données spécifiques du concurrent"""
data = {}
for selector_info in competitor['selectors']:
try:
element = self.driver.find_element(
By.CSS_SELECTOR,
selector_info['selector']
)
data[selector_info['name']] = element.text
except:
data[selector_info['name']] = "Non trouvé"
return data
def generate_report(self):
"""Générer un rapport"""
report = "=== RAPPORT DE VEILLE CONCURRENTIELLE ===\n\n"
for result in self.results:
report += f"Concurrent: {result['competitor']}\n"
report += f"Date: {result['timestamp']}\n"
for key, value in result['data'].items():
report += f" {key}: {value}\n"
report += "\n" + "-"*50 + "\n\n"
return report
def send_email_report(self, report):
"""Envoyer le rapport par email"""
if not self.config.get('email'):
return
email_config = self.config['email']
msg = MIMEText(report)
msg['Subject'] = f"Rapport de veille - {datetime.now().strftime('%Y-%m-%d')}"
msg['From'] = email_config['from']
msg['To'] = email_config['to']
try:
with smtplib.SMTP(email_config['smtp_server'], email_config['smtp_port']) as server:
server.starttls()
server.login(email_config['username'], email_config['password'])
server.send_message(msg)
print("Rapport envoyé par email")
except Exception as e:
print(f"Erreur envoi email : {e}")
# Fichier config.json exemple
config_example = {
"competitors": [
{
"name": "Concurrent A",
"url": "https://competitor-a.com",
"selectors": [
{"name": "prix_produit", "selector": ".price"},
{"name": "stock", "selector": ".stock-status"}
]
}
],
"delay_between_sites": 5,
"email": {
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"from": "votre@email.com",
"to": "destinataire@email.com",
"username": "votre@email.com",
"password": "votre_mot_de_passe"
}
}
# Utilisation
if __name__ == "__main__":
bot = CompetitorMonitorBot()
bot.monitor_competitors()
report = bot.generate_report()
bot.send_email_report(report)
bot.close()
Troubleshooting et solutions aux problèmes courants
Problème : Détection anti-bot
python
def avoid_detection(self):
"""Techniques pour éviter la détection"""
options = webdriver.ChromeOptions()
# Masquer l'automatisation
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
# User-Agent personnalisé
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
# Désactiver les images pour plus de rapidité
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
return options
Problème : Éléments qui changent dynamiquement
python
def handle_dynamic_content(self):
"""Gérer le contenu dynamique"""
# Attendre le chargement AJAX
self.wait.until(
lambda driver: driver.execute_script("return jQuery.active == 0")
)
# Ou attendre un élément spécifique
self.wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "loaded"))
)
Python et Selenium forment une combinaison puissante pour l’automatisation web. En suivant les bonnes pratiques présentées dans ce guide, vous pouvez créer des bots robustes, éthiques et efficaces.
Points clés à retenir :
- Planifiez votre approche : Analysez le site cible avant de coder
- Respectez les limites : Vérifiez robots.txt et conditions d’utilisation
- Gérez les erreurs : Implémentez une gestion d’erreurs robuste
- Testez régulièrement : Les sites web évoluent, vos bots aussi
- Documentez votre code : Facilitez la maintenance future
L’automatisation web ouvre de nombreuses possibilités : monitoring, tests, collecte de données, et bien plus. Avec les bases solides de ce guide, vous êtes maintenant équipé pour créer vos propres solutions d’automatisation.