English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Explication des trois méthodes d'attente dans Python selenium

J'ai constaté que trop de gens ne savent pas comment utiliser l'attente, donc aujourd'hui, je ne peux pas m'empêcher de vous parler de l'importance de l'attente.

Beaucoup de gens dans le groupe demandent, ce menu déroulant est introuvable, ce pop-up ne peut pas être localisé... des problèmes de localisation de toutes sortes, en réalité, dans la plupart des cas, il s'agit de deux problèmes :1 avec frame,2 Il n'y a pas d'attente ajoutée. Ne sachant pas à quel point la vitesse d'exécution de votre code est importante, et à quel point la vitesse de chargement et de rendu du navigateur est importante, imaginez que Flash et Powerman s'entendent pour combattre un monstre, puis Flash revient après avoir combattu et demande à Powerman pourquoi il est encore en train de s'habiller et de ne pas être sorti. Powerman se sent insulté, pense que Flash le prend pour faible, décide de ne plus jouer et lance une exception pour abandonner.

Alors, comment pouvons-nous prendre en compte le chargement lent de Powerman ? Il n'y a qu'une seule solution, c'est d'attendre. Parlons des trois méthodes d'attente, et je les expliquerai un par un :

1. Attente forcée

La première méthode est aussi la plus simple et la plus brutale, c'est l'attente forcée sleep(xx), qui force Flash à attendre xx secondes, peu importe si Powerman peut suivre ou s'il est déjà arrivé avant, il doit attendre xx secondes.

Voyons le code :

# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get('https://huilansame.github.io
sleep(3) # Attente forcée3secondes avant de passer à l'étape suivante
print driver.current_url
driver.quit()

Cela s'appelle l'attente forcée, que le navigateur ait terminé de charger ou non, le programme doit attendre.3secondes,3Une fois la seconde écoulée, continuez l'exécution du code suivant, ce qui est très utile pour le débogage. Parfois, vous pouvez attendre ainsi dans le code, mais je ne recommande pas d'utiliser ce type d'attente en permanence, car il est trop rigide et peut sérieusement affecter la vitesse d'exécution du programme.

2. Attente implicite

La deuxième méthode s'appelle l'attente implicite, implicitly_wait(xx), l'importance de l'attente implicite est que, Flash et Powerman s'entendent que, peu importe où Flash va, il doit attendre Powerman xx secondes. Si Powerman arrive dans ce délai, ils partiront immédiatement pour combattre le monstre. Si Powerman ne vient pas à temps, Flash ira seul, et naturellement, il attendra Powerman pour vous lancer une exception.

Voyons le code :

# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(30) # Attente implicite, au maximum de30 second
driver.get('https://huilansame.github.io
print driver.current_url
driver.quit()

L'attente implicite définit une durée maximale d'attente. Si la page web est chargée dans ce délai, l'étape suivante est exécutée, sinon elle attend jusqu'à la fin du délai, puis exécute l'étape suivante. Attention, il y a un inconvénient ici, c'est que le programme attend que tout le chargement de la page soit terminé, c'est-à-dire généralement lorsque vous voyez que le cercle dans la barre d'état du navigateur cesse de tourner, il exécute l'étape suivante. Mais parfois, les éléments que vous voulez sont déjà chargés, mais à cause de certaines choses lentes comme des js, je dois attendre que la page soit complètement terminée pour passer à l'étape suivante. Que faire si je veux que l'étape suivante soit exécutée dès que l'élément souhaité apparaît ? Il y a une solution, cela dépend de la autre méthode d'attente fournie par selenium - l'attente explicite wait.

Il est important de noter que l'attente implicite agit sur tout le cycle du driver, donc il suffit de le configurer une fois. J'ai vu quelqu'un utiliser l'attente implicite comme sleep, partout où il allait...

3. Attente explicite

La troisième méthode consiste en une attente explicite, WebDriverWait, en association avec les méthodes until() et until_not() de cette classe, ce qui permet de réaliser une attente flexible en fonction des conditions. Son principal objectif est : le programme regarde toutes les xx secondes, si la condition est remplie, il exécute l'étape suivante, sinon il continue d'attendre jusqu'à ce que le temps maximal soit atteint, puis lève une exception TimeoutException.

Regardons un exemple de code :

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.implicitly_wait(10) # L'attente implicite et explicite peuvent être utilisées ensemble, mais attention : la durée maximale de l'attente est la plus grande des deux
driver.get('https://huilansame.github.io
locator = (By.LINK_TEXT, 'CSDN')
try:
  WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
  print driver.find_element_by_link_text('CSDN').get_attribute('href')
finally:
  driver.close()

上例中,我们设置了隐性等待和显性等待,在其他操作中,隐性等待起决定性作用,在WebDriverWait..中显性等待起主要作用,但要注意的是:最长的等待时间取决于两者之间的大者,此例中为20,如果隐性等待时间 > 显性等待时间,则该句代码的最长等待时间等于隐性等待时间。

我们主要用到了WebDriverWait类与expected_conditions模块,下面博主带大家细看一下这两个模块:

WebDriverWait

wait模块的WebDriverWait类是显性等待类,先看下它有哪些参数与方法:

selenium.webdriver.support.wait.WebDriverWait(类)
__init__
  driver: 传入WebDriver实例,即我们上例中的driver
  timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
  poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5seconds
  ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,
      则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。
until
  method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False
  message: 如果超时,抛出TimeoutException,将message传入异常
until_not与until相反,until是当某元素出现或什么条件成立则继续执行,
    until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。
  method
  message

看了以上内容基本上很清楚了,调用方法如下:

WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)

需要注意的是,until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:

WebDriverWait(driver, 10).until(driver.find_element_by_id('kw'))  # erreur

C'est une mauvaise utilisation, les paramètres doivent être appelables, c'est-à-dire que cet objet doit avoir une méthode __call__(), sinon il sera lancé une exception :

TypeError: 'xxx' object is not callable

Ici, vous pouvez utiliser diverses conditions du module expected_conditions fourni par selenium, ou utiliser les méthodes is_displayed() 、is_enabled()、is_selected() de WebElement, ou utiliser vos propres méthodes encapsulées, alors regardons les conditions fournies par selenium :

expected_conditions

expected_conditions est un module de selenium, qui contient une série de conditions utilisables pour juger :
selenium.webdriver.support.expected_conditions(module)
Ces deux conditions vérifient le title, vérifient si le paramètre title est égal ou contient driver.title
title_is
title_contains
Ces deux conditions vérifient si l'élément apparaît, les paramètres entrés sont tous de type tuple locator, comme (By.ID, 'kw')
Comme son nom l'indique, une passe si un élément conforme est chargé, l'autre doit que tous les éléments conformes soient chargés
presence_of_element_located
presence_of_all_elements_located
Ces trois conditions vérifient si l'élément est visible, les deux premières entrent les paramètres de type tuple locator, la troisième entre WebElement
La première et la troisième sont en fait les mêmes
visibility_of_element_located
invisibility_of_element_located
visibility_of
Ces deux conditions jugent si un texte apparaît dans un élément, une juge le texte de l'élément, l'autre juge la valeur de l'élément
text_to_be_present_in_element
text_to_be_present_in_element_value
Cette condition juge si le frame peut être inséré, peut entrer le tuple locator ou directement entrer le mode de localisation : id, name, index ou WebElement
frame_to_be_available_and_switch_to_it
Cette condition juge s'il y a une alerte apparue
alert_is_present
Cette condition juge si un élément est cliquable, transmet le locator
element_to_be_clickable
Ces quatre conditions jugent si un élément est sélectionné, la première condition transmet un objet WebElement, la deuxième transmet un tuple locator
Le troisième argument transmet l'objet WebElement et l'état, retourne True s'ils sont égaux, sinon False
Le quatrième argument transmet le locator et l'état, retourne True s'ils sont égaux, sinon False
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
La dernière condition juge si un élément reste dans le DOM, transmet un objet WebElement, peut juger si la page a été rafraîchie
staleness_of

Voici tous17Une condition, combinée avec until et until_not, peut réaliser de nombreuses jugements, et si elle peut être encapsulée de manière flexible, elle améliorera considérablement la stabilité du script.

Aujourd'hui, je partage ces contenus, vous pouvez laisser un message pour échanger avec moi, j'espère pouvoir aider les étudiants qui en ont besoin. Merci de votre soutien à ce site !

Déclaration : le contenu de cet article est issu du réseau, la propriété intellectuelle appartient à ses auteurs respectifs, le contenu est apporté par les utilisateurs d'Internet et téléversé spontanément. Ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme, et n'assume aucune responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)

Vous pourriez aussi aimer