Maison >développement back-end >Tutoriel Python >Créer une automatisation Web robuste avec Selenium et Python
L'automatisation du Web est désormais un outil indispensable dans le développement et les tests de logiciels modernes. Dans ce didacticiel complet Selenium Python, vous apprendrez à créer un cadre d'automatisation Web robuste capable de gérer des scénarios du monde réel. Si vous souhaitez mettre en œuvre des tests automatisés en Python ou créer des solutions complexes d'automatisation du web scraping, ce guide vous présentera des approches testées par l'industrie et les meilleures pratiques Selenium.
L'automatisation du Web est vitale dans le développement, les tests et la collecte de données de logiciels modernes. Ses applications vont du test de bout en bout des applications Web à la simplification des flux de travail répétitifs, tels que la soumission de formulaires ou le web scraping. Bien que l'intégration Selenium WebDriver Python offre des fonctionnalités puissantes, une automatisation Web robuste ne se limite pas à l'écriture de scripts pour imiter les interactions des utilisateurs. Il s'agit de concevoir des flux de travail et des cadres maintenables, adaptables et résilients aux modifications apportées à l'application Web cible.
Vous trouverez ci-dessous les aspects clés que nous aborderons tout au long de ce tutoriel :
Nous allons créer un projet d'automatisation du web scraping pour un suivi des prix sur les sites Web de commerce électronique en utilisant Books to Scrape comme site de démonstration pour démontrer ces concepts tout en adhérant aux meilleures pratiques de Selenium.
Pour suivre ce tutoriel, vous aurez besoin de :
Le code de ce tutoriel est disponible sur notre dépôt github, n'hésitez pas à le cloner pour suivre.
Configurons un environnement de développement approprié et installons les packages Python nécessaires. Tout d'abord, créez le dossier du projet et un nouvel environnement virtuel en exécutant les commandes ci-dessous :
mkdir price_tracker_automation && cd price_tracker_automation python3 -m venv env source env/bin/activate
Ensuite, créez et ajoutez les packages Python suivants à votre fichier exigences.txt :
selenium==4.16.0 webdriver-manager==4.0.1 python-dotenv==1.0.0 requests==2.31.0
Dans le code ci-dessus, nous avons défini nos dépendances principales. Le package Selenium constitue la base de notre cadre d'automatisation Web, tandis que webdriver-manager gère automatiquement la gestion des pilotes de navigateur. Le package python-dotenv est destiné à la configuration de l'environnement et le package request est destiné à la gestion des requêtes HTTP.
Exécutez maintenant la commande ci-dessous pour installer tous les packages Python dans votre fichier exigences.txt en exécutant la commande ci-dessous :
pip install -r requirements.txt
Enfin, créez la structure de dossiers suivante pour notre projet :
mkdir price_tracker_automation && cd price_tracker_automation python3 -m venv env source env/bin/activate
Ici, nous établissons une structure de projet modulaire suivant les meilleures pratiques d'ingénierie logicielle. Le répertoire core contient nos principaux composants d'automatisation, tandis que la database gère la persistance des données.
Une fois l'environnement du projet, les dépendances et les structures de dossiers créés, passons à la création de l'outil d'automatisation de suivi des prix à l'aide de Selenium et Python.
Implémentons notre système de gestion de navigateur, il s'agit d'un composant important pour une intégration stable de Selenium WebDriver Python. Ajoutez l'extrait de code ci-dessous à votre fichier core/browser.py :
selenium==4.16.0 webdriver-manager==4.0.1 python-dotenv==1.0.0 requests==2.31.0
Le code ci-dessus crée une classe BrowserManager qui gère l'initialisation et la configuration de WebDriver. La classe implémente les meilleures pratiques de Selenium en configurant les options de Chrome pour la stabilité et les performances. Le paramètre headless permet d'exécuter des tests sans fenêtre de navigateur visible, ce qui est crucial pour les pipelines CI/CD.
Ajoutez maintenant les méthodes suivantes à la classe BrowserManager pour implémenter les fonctionnalités de gestion de base du navigateur :
pip install -r requirements.txt
Dans le code ci-dessus, la méthode start_browser utilise webdriver-manager pour gérer automatiquement l'installation et les mises à jour des pilotes, tandis que close_browser assure un nettoyage approprié des ressources. L'implémentation inclut une configuration d'attente implicite pour gérer le chargement dynamique des pages avec élégance.
Ensuite, passons à la mise en œuvre du système d'interaction des éléments, ceci est important dans tout framework d'automatisation Web car il nous permet de détecter et d'interagir avec les éléments de manière fiable tout en suivant les meilleures pratiques de Selenium. Ajoutez les extraits de code à votre core/element_handler.py
price_tracker_automation/ ├── core/ │ ├── browser.py | ├── scraper.py │ └── element_handler.py ├── database/ │ └── db_manager.py ├── notifications/ | └── price_alert.py ├── requirements.txt ├── run.py └── main.py
Dans le code ci-dessus, nous avons créé une classe ElementHandler, qui encapsule les modèles d'interaction Selenium WebDriver Python. La classe accepte une instance WebDriver et un paramètre de délai d'attente configurable.
Mettez à jour votre classe ElementHandler pour ajouter des méthodes d'interaction avec les éléments de base :
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support import expected_conditions as EC import logging class BrowserManager: def __init__(self, headless=False): self.options = webdriver.ChromeOptions() if headless: self.options.add_argument('--headless') # Add additional stability options self.options.add_argument('--no-sandbox') self.options.add_argument('--disable-dev-shm-usage') self.options.add_argument('--disable-gpu') self.driver = None self.logger = logging.getLogger(__name__)
Les méthodes ci-dessus utilisent WebDriverWait et Expected_conditions de Selenium pour détecter les éléments afin de pouvoir également gérer les pages Web dynamiques où les éléments peuvent se charger de manière asynchrone.
Ajoutez une autre méthode pour implémenter la logique d'extraction de texte :
def start_browser(self): """Initialize and return a ChromeDriver instance""" try: service = webdriver.ChromeService() self.driver = webdriver.Chrome(service=service, options=self.options) self.driver.implicitly_wait(10) return self.driver except Exception as e: self.logger.error(f"Failed to start browser: {str(e)}") raise def close_browser(self): """Safely close the browser""" if self.driver: self.driver.quit() self.driver = None
La méthode inclut une logique de nouvelle tentative pour gérer StaleElementReferenceException, ce qui constitue un défi courant dans l'automatisation Web.
Développons maintenant notre principale fonctionnalité de scraping, en incorporant des concepts de tests automatisés Python et une gestion robuste des erreurs. Ajoutez les extraits de code ci-dessous à votre fichier core/scraper.py :
mkdir price_tracker_automation && cd price_tracker_automation python3 -m venv env source env/bin/activate
Dans le code ci-dessus, nous avons créé la classe BookScraper qui intègre nos composants de navigateur et de gestion des éléments. La classe suit le modèle Page Object Model, un concept clé dans la conception d'un cadre d'automatisation Web, en centralisant les localisateurs d'éléments et en fournissant une API propre pour les opérations de scraping.
Ensuite, mettez à jour la classe BookScraper pour ajouter les principales méthodes d'extraction des données produit :
selenium==4.16.0 webdriver-manager==4.0.1 python-dotenv==1.0.0 requests==2.31.0
Les méthodes ci-dessus utilisent une approche structurée pour collecter des informations sur le produit, en conservant des journaux détaillés pour le débogage et la surveillance.
Implémentons la couche de base de données de notre framework d'automatisation Web, qui gérera le stockage persistant de nos données récupérées. Ce composant nous permettra de suivre l'évolution des prix au fil du temps. Ajoutez les extraits de code ci-dessous à votre base de données/db_manager.py :
pip install -r requirements.txt
Dans le code ci-dessus, nous avons défini notre classe DatabaseManager qui gère toutes les opérations de base de données. Nous avons utilisé SQLite pour plus de simplicité et de portabilité, pour éviter d'avoir à installer et configurer une base de données et SQLite est également idéal pour notre projet d'automatisation du web scraping puisque nous ne stockons pas de grandes quantités de données.
Ensuite, mettez à jour votre base de données/db_manager.py pour ajouter la méthode d'initialisation de la base de données :
price_tracker_automation/ ├── core/ │ ├── browser.py | ├── scraper.py │ └── element_handler.py ├── database/ │ └── db_manager.py ├── notifications/ | └── price_alert.py ├── requirements.txt ├── run.py └── main.py
Ici, nous établissons notre schéma de base de données à l'aide d'instructions SQL DDL et créons des tables séparées pour les produits et l'historique des prix, avec des relations et des contraintes appropriées qui nous permettront de suivre les prix et d'effectuer une analyse historique sur les données que nous stockons.
Ajoutons maintenant une autre méthode pour enregistrer les données dans la base de données :
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support import expected_conditions as EC import logging class BrowserManager: def __init__(self, headless=False): self.options = webdriver.ChromeOptions() if headless: self.options.add_argument('--headless') # Add additional stability options self.options.add_argument('--no-sandbox') self.options.add_argument('--disable-dev-shm-usage') self.options.add_argument('--disable-gpu') self.driver = None self.logger = logging.getLogger(__name__)
Dans le code ci-dessus, nous avons implémenté la logique de persistance des données à l'aide de requêtes paramétrées pour empêcher l'injection SQL. La méthode gère à la fois les opérations d'insertion et de mise à jour à l'aide de la clause ON CONFLICT de SQLite.
Lions le tout avec notre classe d'application principale, en incorporant tous les éléments de notre implémentation Python Selenium WebDriver. Ajoutez les extraits de code ci-dessous à votre fichier main.py :
def start_browser(self): """Initialize and return a ChromeDriver instance""" try: service = webdriver.ChromeService() self.driver = webdriver.Chrome(service=service, options=self.options) self.driver.implicitly_wait(10) return self.driver except Exception as e: self.logger.error(f"Failed to start browser: {str(e)}") raise def close_browser(self): """Safely close the browser""" if self.driver: self.driver.quit() self.driver = None
Dans le code ci-dessus, nous créons la classe principale PriceTracker qui orchestre tous les composants de notre solution d'automatisation du web scraping. La classe PriceTracker suit des modèles d'injection de dépendances pour maintenir la modularité et la testabilité.
Ensuite, mettez à jour notre classe PriceTracker pour ajouter les méthodes de suivi de base :
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, StaleElementReferenceException class ElementHandler: def __init__(self, driver, timeout=10): self.driver = driver self.timeout = timeout
Ici, nous avons implémenté la principale logique de suivi des produits qui gère le web scraping et stocke les données récupérées.
Créons un script d'exécution pour exécuter notre script d'automatisation. Ajoutez les extraits de code suivants à votre fichier run.py :
def wait_for_element(self, locator, timeout=None): """Wait for element with retry mechanism""" timeout = timeout or self.timeout try: element = WebDriverWait(self.driver, timeout).until( EC.presence_of_element_located(locator) ) return element except TimeoutException: raise TimeoutException(f"Element {locator} not found after {timeout} seconds") def get_text_safely(self, locator, timeout=None): """Safely get text from element with retry mechanism""" max_retries = 3 for attempt in range(max_retries): try: element = self.wait_for_element(locator, timeout) return element.text.strip() except StaleElementReferenceException: if attempt == max_retries - 1: raise continue
Exécutez maintenant la commande suivante sur votre terminal pour exécuter le script :
mkdir price_tracker_automation && cd price_tracker_automation python3 -m venv env source env/bin/activate
La commande ci-dessus affichera le résultat sur la capture d'écran ci-dessous :
À partir du script ci-dessus, vous pouvez voir que notre script d'automatisation suit le prix pour toutes les URL spécifiées.
Notre implémentation actuelle suit et enregistre uniquement les prix des produits. Après avoir suivi les prix, améliorons notre système de suivi des prix pour informer les utilisateurs des changements de prix. Ajoutez les extraits de code suivants à votre fichier notifications/price_alert.py :
selenium==4.16.0 webdriver-manager==4.0.1 python-dotenv==1.0.0 requests==2.31.0
Dans l'extrait de code ci-dessus, nous avons créé une classe PriceAlertManager avec des dépendances essentielles. Le gestionnaire prend une instance du gestionnaire de base de données comme paramètre et configure la journalisation pour suivre les opérations d'alerte. La classe utilise des jointures complexes pour comparer les prix actuels et précédents. Ensuite, nous avons mis en œuvre un calcul dynamique du pourcentage de changement de prix et créé un dictionnaire structuré pour les informations sur les changements de prix.
Ensuite, mettez à jour votre classe PriceAlertManager pour ajouter une fonctionnalité de notification par e-mail :
pip install -r requirements.txt
Ici, nous avons créé une notification par e-mail à l'aide des bibliothèques de messagerie et SMTP de Python. L'implémentation utilise la classe MIMEText pour créer des messages électroniques correctement formatés. Le corps de l'e-mail est généré dynamiquement à l'aide de f-strings, intégrant des informations détaillées sur les changements de prix avec un formatage précis de la devise.
Modifions maintenant notre script d'exécution pour inclure des alertes de prix :
price_tracker_automation/ ├── core/ │ ├── browser.py | ├── scraper.py │ └── element_handler.py ├── database/ │ └── db_manager.py ├── notifications/ | └── price_alert.py ├── requirements.txt ├── run.py └── main.py
Maintenant, si vous exécutez à nouveau le script, il suivra les prix des produits et vous alertera des produits dont les prix ont changé comme dans la capture d'écran ci-dessous :
Peut-être pouvez-vous exécuter ce script dans une tâche cron pour suivre les prix des produits et vous alerter en temps réel des changements de prix sans avoir à l'exécuter manuellement à chaque fois.
Par exemple. 0 */6 * * * python run.py --urls
"http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
"http://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"
"http://books.toscrape.com/catalogue/soumission_998/index.html"
Tout au long de ce didacticiel, vous avez appris à créer un outil d'automatisation Web robuste à l'aide de Selenium et Python. Nous avons commencé par comprendre les fondamentaux de l'automatisation web, puis nous avons mis en place un environnement de développement pour l'outil Price Traker que nous avons construit pour les démonstrations de ce tutoriel. Ensuite, nous sommes allés plus loin en créant l'application Price Tracker qui suit les prix des produits et alerte les utilisateurs des changements de prix. Maintenant que vous avez ces connaissances, quel outil allez-vous créer ensuite. Faites-le-moi savoir dans la section commentaires. Bon codage !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!