Quelques articles de ce carnet sont consacrés au développement de scripts de navigation web automatique avec Python, qui font appel à la librairie Selenium.
Avez-vous tenté récemment de reproduire le code, l’adapter ou simplement tester les scripts mis à disposition ? Si c’est le cas, vous avez peut-être eu la mauvaise surprise de n’obtenir rien de plus que des messages d’erreur… Et c’est normal ! Les dernières versions de Selenium introduisent des changements qui rendent obsolètes certains principes des versions précédentes.
Voici comment vous en sortir avec une installation à jour.
Cet article présente une mise à jour d’un ancien script que vous pouvez retrouver sur Github et sur Gitlab.
Dans de précédents articles, je vous ai montré quelques éléments du fonctionnement de la librairie Python selenium
:
- Dans Cartographier des données linguistiques avec Python – 4 : déclarer un navigateur pour la navigation scriptée (
webdriver
), automatiser une capture d’écran. - Dans Navigation web automatique avec Python : accéder à une page web, entrer une séquence tapée au clavier, cliquer sur un lien pour changer de page de façon automatique.
Si dans l’ensemble la logique à appliquer et une bonne partie des explications apportées sont encore tout à fait valides, il y a également des éléments qui ont significativement changé dans leurs versions plus récentes.
Je vais me baser sur le script téléchargeable qui accompagne l’article Navigation web automatique avec Python pour vous montrer comment obtenir à nouveau un programme fonctionnel.
Importer la librairie et les modules
J’expliquais dans cet article que pour pouvoir utiliser selenium
et déclarer un navigateur virtuel (webdriver
), il était nécessaire de télécharger localement un exécutable correspondant au navigateur choisi1. Pour utiliser différents navigateurs il fallait alors télécharger plusieurs exécutables, et récupérer manuellement les nouvelles versions en cas de mises à jour.
Ce n’est plus le cas. Il est maintenant possible de les importer par l’intermédiaire d’un objet Service
et les gérer avec webdriver_manager
.
Ancienne version2 :
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
Nouvelle version :
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
Vous avez peut-être remarqué que j’ai également importé la classe By
de selenium.webdriver.common.by
. Elle ne sera pas utile dès l’instanciation d’un objet webdriver.Firefox()
mais interviendra dans l’interaction avec les pages web.
Déclarer un navigateur
La déclaration du navigateur s’effectue toujours via une instance de webdriver.Firefox()
, mais le chemin d’accès de l’exécutable est remplacé par une instance de Service
.
Ancienne version :
options = webdriver.FirefoxOptions()
options.headless = True
webdrivers_path = "./WebDrivers/"
driver = webdriver.Firefox(webdrivers_path, options=options)
Nouvelle version :
options = webdriver.FirefoxOptions()
options.add_argument('--headless')
driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()), options=options)
Il y a aussi quelques différences dans la mise en place des options. Si elles se font toujours avec une instance de webdriver.FirefoxOptions()
passée en paramètre option
lors de l’instanciation de l’objet webdriver.Firefox
, la syntaxe n’est plus la même. Par exemple pour ajouter l’option headless
il faut maintenant utiliser la syntaxe options.add_argument('--headless')
plutôt que options.headless = True
, utilisée dans les versions précédentes.
Naviguer automatiquement
Le script fourni avec l’article Navigation web automatique avec Python comporte une fonction nommée enter_konami_code()
qui permet d’automatiser l’appui sur une série de touches du clavier.
Elle se présentait alors comme ceci3 :
def enter_konamicode(url):
driver.get(url)
body = driver.find_element_by_tag_name("body")
konamicode = [Keys.ARROW_UP, Keys.ARROW_UP,
Keys.ARROW_DOWN, Keys.ARROW_DOWN,
Keys.ARROW_LEFT, Keys.ARROW_RIGHT,
Keys.ARROW_LEFT, Keys.ARROW_RIGHT,
"b", "a"]
body.send_keys(konamicode)
time.sleep(1)
konamialert = driver.find_element_by_id("konamicongrats")
message = konamialert.text
return message
Cette fonction est encore valide d’un point de vue algorithmique mais des éléments de sa syntaxe sont obsolètes.
Les méthodes de type find_element_by_tag_name()
ou find_element_by_id()
sont à présent regroupées en tant que méthode find_element()
unique. Le locator, c’est-à-dire la caractéristique de l’élément HTML sur laquelle driver
va baser sa stratégie de localisation, est exprimé avec By
.
Par exemple, la fonction enter_konamicode()
inclut une instruction pour repérer l’élément portant l’id konamicongrats
.
Ancienne version :
konamialert = driver.find_element_by_id("konamicongrats")
Nouvelle version :
konamialert = driver.find_element(By.ID, "konamicongrats")
Voici donc la version mise à jour de la fonction complète4 :
def enter_konamicode(url):
driver.get(url)
body = driver.find_element(By.TAG_NAME, "body")
konamicode = [Keys.ARROW_UP, Keys.ARROW_UP,
Keys.ARROW_DOWN, Keys.ARROW_DOWN,
Keys.ARROW_LEFT, Keys.ARROW_RIGHT,
Keys.ARROW_LEFT, Keys.ARROW_RIGHT,
"b", "a"]
body.send_keys(konamicode)
time.sleep(1)
konamialert = driver.find_element(By.ID, "konamicongrats")
message = konamialert.text
return message
Faire une capture d’écran
Certaines choses n’ont pas changé ! Vous avez pu le voir ci-dessus avec get()
et send_keys()
. C’est aussi le cas de click()
ou encore de save_screenshot()
, notamment.
La syntaxe présentée dans l’article de cartographie linguistique reste valide :
driver.save_screenshot("mon_image.png")
- Par exemple, geckodriver pour Firefox. [↩]
- Cf script. [↩]
- Le script d’origine comporte des commentaires, je les ai supprimés ici pour une meilleure lisibilité. [↩]
- Les lignes modifiées sont en caractères gras. [↩]
OpenEdition vous propose de citer ce billet de la manière suivante :
Alexander Delaporte (14 janvier 2025). Navigation web automatique avec Python, mise à jour. Tekipaki. Consulté le 17 février 2025 à l’adresse https://doi.org/10.58079/1332e