J'ai écrit un script en python en combinaison avec du sélénium pour me connecter à un site Web. Le problème est que mon script est parfois connecté avec succès, mais la plupart du temps, il rencontre un curseur qui est destiné à appuyer et à glisser vers la droite.
Comment puis-je laisser mon script faire glisser ce bouton vers la droite?
J'ai essayé avec: p >
<div id="nc_1_n1t" class="nc_scale"> <div id="nc_1__bg" class="nc_bg" style="width: 0px;"></div> <span id="nc_1_n1z" class="nc_iconfont btn_slide" data-spm-anchor-id="0.0.0.i1.3f9579f4qCwuHp" style="left: 0px;">î</span> <div id="nc_1__scale_text" class="scale_text slidetounlock"><span class="nc-lang-cnt" data-nc-lang="_startTEXT">Please slide to verify</span></div> <div id="nc_1_clickCaptcha" class="clickCaptcha" style="top: -118px; height: 235px;"> <div class="clickCaptcha_text"> <b id="nc_1__captcha_text" class="nc_captch_text"></b> <i id="nc_1__btn_2" class="nc_iconfont nc_btn_2 btn_refresh">î</i> </div> <div class="clickCaptcha_img"></div> <div class="clickCaptcha_btn"></div> </div> <div id="nc_1_imgCaptcha" class="imgCaptcha" style="top: -118px; min-height: 290px; height: 189px;"> <div class="imgCaptcha_text"><input id="nc_1_captcha_input" maxlength="6" type="text" style="ime-mode:disabled"></div> <div class="imgCaptcha_img" id="nc_1__imgCaptcha_img"></div> <i id="nc_1__btn_1" class="nc_iconfont nc_btn_1 btn_refresh" onclick="document.getElementById('nc_1__imgCaptcha_img').children[0].click()">î</i> <div class="imgCaptcha_btn"> <div id="nc_1__captcha_img_text" class="nc_captcha_img_text"></div> <div id="nc_1_scale_submit" class="nc_scale_submit"></div> </div> </div> <div id="nc_1_cc" class="nc-cc"></div> <i id="nc_1__voicebtn" tabindex="0" role="button" class="nc_voicebtn nc_iconfont" style="display:none">î</i> <b id="nc_1__helpbtn" class="nc_helpbtn"><span class="nc-lang-cnt" data-nc-lang="_learning">help</span></b> </div>
Éléments Html connectés à ce curseur:
from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def sign_in(): driver.get("https://login.aliexpress.com/") wait.until(EC.frame_to_be_available_and_switch_to_it(wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#alibaba-login-box"))))) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input#fm-login-id"))).send_keys("someEmail") wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input#fm-login-password"))).send_keys("somePassword") wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "button[class$='password-login']"))).click() #the following line is for handling the slider but it doesn't do anything item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".nc_wrapper .btn_slide"))) ActionChains(driver).move_to_element(item).perform() if __name__ == '__main__': driver = webdriver.Chrome() wait = WebDriverWait(driver,10) sign_in()
3 Réponses :
Essayez d'utiliser Actions Voici le code c # pour référence
int x = 100; int y = 100; Actions moveOffset = new Actions(driver); moveOffset.MoveByOffset(x,y).Perform(); //set your suitable (x,y) offset value
une fois que vous avez maintenu le curseur, essayez de le déplacer vers la valeur de décalage souhaitée
//following code will click and hold the slider string Xpath=""; //set xpath for desired element to be click and hold Actions clickHold = new Actions(driver); IWebElement element = driver.FindElement(By.XPath(Xpath)); clickHold.ClickAndHold(element).Perform();
L'exemple de code (en java) pour l'opération de curseur de gauche à droite est ci-dessous.
Actions slider=new Actions(driver); slider.clickAndHold("xpath of slider"); slider.movebyoffset(x,y).build.perform();
à la place de «x» et «y», vous pouvez donner la valeur de décalage réelle selon votre application.
Je ne parviens pas à afficher le curseur sur le site Web lié à la question, j'ai donc fourni une solution en utilisant un autre site qui a un élément de curseur (je suppose que la fonctionnalité est similaire à celle sur aliexpress
# Define slider elements and element that will be shown when you successfully log in SLIDER_CONTAINER = (By.CSS_SELECTOR, ".nc-lang-cnt") SLIDER = (By.CSS_SELECTOR, ".nc_wrapper .btn_slide") ELEMENT_TO_FIND = (By.ID, "search-key") # Invoke the explicit wait that will deal with the slider if it is displayed wait.until(wait_for_element_while_verifying_slider(ELEMENT_TO_FIND, SLIDER_CONTAINER, SLIDER))
L'élément clé ici est la ligne Effectuer une action glissante
. Nous devons identifier deux éléments spécifiques:
Une fois que nous avons trouvé ces deux éléments, nous utilisons la classe actions pour cliquer et maintenir l'élément que nous devons faire glisser, puis nous le faisons glisser de la largeur de l'élément contenant le long de l'axe x (comme indiqué en utilisant slider_container.size ['width']
), sans changer l'axe des y.
Cela devrait résoudre votre problème de glissement, mais vous aurez un autre problème, vous devez déterminer si le curseur était affiché ou vous étiez connecté au site Web. Pour ce faire, vous allez avoir besoin d'une condition attendue qui vérifie l'existence de 2 éléments:
Si l'élément que vous vous attendez à voir lorsque vous vous connectez est affiché, vous n'avez rien à faire. Si le curseur est affiché, vous devrez exécuter la logique ci-dessus pour faire glisser la barre.
* Modifier *
Pour améliorer un peu de plus, vous pouvez mettre le code glissant dans une ExpectedCondition comme ceci:
ELEMENT_TO_FIND = (By.XPATH, "//div[.=\"Slide To Submit\"]")
Ceci recherchera un élément que vous espérez voir apparaître lorsque vous vous connectez. Si l'élément que vous s'attend à voir lorsque vous vous êtes connecté avec succès ne s'affiche pas, il essaiera alors de localiser les éléments du curseur et d'interagir avec eux pour traiter la vérification de la diapositive. Notez qu'une fois qu'il essaie d'effectuer la vérification de la diapositive, la condition attendue renverra False, ce qui l'obligera à vérifier si l'élément connecté attendu s'affiche à nouveau.
Vous pouvez l'utiliser dans votre code comme ceci:
# Instantiate objects driver = webdriver.Chrome() wait = WebDriverWait(driver, 10) # Load page and fill in input elements driver.get("http://kthornbloom.com/slidetosubmit/") driver.find_element(By.NAME, "name").send_keys("Fred") driver.find_element(By.NAME, "email").send_keys("fred@example.com") # Define slider elements and element that will be shown when you successfully log in SLIDER_CONTAINER = (By.CSS_SELECTOR, ".slide-submit") SLIDER = (By.CSS_SELECTOR, ".slide-submit-thumb") ELEMENT_TO_FIND = (By.XPATH, "//div[.=\"Looks Like You're Human!\"]") # Invoke the explicit wait that will deal with the slider if it is displayed wait.until(wait_for_element_while_verifying_slider(ELEMENT_TO_FIND, SLIDER_CONTAINER, SLIDER))
L'exemple ci-dessus utilise le même exemple de site Web que ci-dessus. Pour le faire expirer, vous pouvez remplacer ELEMENT_TO_FIND
par quelque chose qui n'existe pas. Pour le faire passer sans glisser, vous pouvez modifier ELEMENT_TO_FIND
pour être:
class wait_for_element_while_verifying_slider(object): def __init__(self, locator, slider_container_locator, slider_locator): self.locator = locator self.slider_container_locator = slider_container_locator self.slider_locator = slider_locator def __call__(self, _driver): try: return _driver.find_element(*self.locator) except (NoSuchElementException, StaleElementReferenceException): container = _driver.find_elements(*self.slider_container_locator) slider = _driver.find_elements(*self.slider_locator) if len(container) > 0 and len(slider) > 0: actions = ActionChains(_driver) actions.move_to_element(slider[0]).click_and_hold().move_by_offset(container[0].size['width'], 0).release().perform() return False
En utilisant le code que vous avez fourni dans votre commentaire, je m'attendrais à ce que ce qui suit travailler sur le site aliexpress:
from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait # Instantiate objects driver = webdriver.Chrome() actions = ActionChains(driver) # Load page and fill in input elements driver.get("http://kthornbloom.com/slidetosubmit/") driver.find_element(By.NAME, "name").send_keys("Fred") driver.find_element(By.NAME, "email").send_keys("fred@example.com") # Find slider elements slider_container = driver.find_element(By.CSS_SELECTOR, ".slide-submit") slider = driver.find_element(By.CSS_SELECTOR, ".slide-submit-thumb") # Perform sliding action actions.move_to_element(slider).click_and_hold().move_by_offset(slider_container.size['width'], 0).release().perform() # Browser intentionally left open so that you can see what happened when the test was run!
Question mise à jour pour essayer de vous aider. Vous pourriez probablement le rendre encore plus propre, mais je vous laisse le soin :)
Les autres capacités de action chain incluent la souris vers le bas ( Actions
click_and_hold ()
), déplacement de la souris (move_by_offset ()
) et souris vers le haut (release ()
).Est-il possible de partager le nom d'utilisateur et le mot de passe du test pour la connexion.
Peut-être pourriez-vous fournir une URL vers un site Web avec lequel je peux travailler et assurer une solution fonctionnelle?
Ne montre jamais le curseur pour moi :(
Ce curseur apparaît lorsque vous exécutez le script deux fois de suite @Ardesco.
J'ai dû le parcourir environ 70 ~ fois maintenant, parfois avec jusqu'à 5 threads en parallèle et je n'obtiens toujours pas le curseur. Vous devez faire quelque chose de spécifique qui déclenche une vérification supplémentaire, sinon vous martelez vraiment le serveur.