3
votes

Impossible de laisser mon script glisser un bouton vers la droite

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()


6 commentaires

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.


3 Réponses :


1
votes

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();


0 commentaires

1
votes

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.


0 commentaires

6
votes

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:

  1. L'élément que nous allons faire glisser
  2. Le conteneur qui contient cet élément

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:

  1. Le curseur.
  2. Un élément que vous vous attendez à voir lorsque vous vous êtes connecté avec succès.

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!


1 commentaires

Question mise à jour pour essayer de vous aider. Vous pourriez probablement le rendre encore plus propre, mais je vous laisse le soin :)