无法让我的脚本向右滑动按钮

时间:2019-06-30 11:17:46

标签: python python-3.x selenium selenium-webdriver web-scraping

我已经用python与硒结合编写了脚本来登录网站。关键是我的脚本有时会成功登录,但大多数情况下会遇到一个滑块,该滑块旨在向右滑动并向右滑动。

如何让我的脚本将该按钮向右滑动?

我尝试过:

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

与该滑块连接的HTML元素:

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

2 个答案:

答案 0 :(得分:5)

我无法使滑块显示在问题中链接的网站上,因此我提供了使用具有滑块元素的另一个网站的解决方案(我假设功能类似于速卖通上的功能)网站)。

data.profile_report()

此处的关键部分是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. 我们要滑动的元素
  2. 保存此元素的容器

找到这两个元素后,我们将使用动作类单击并按住需要滑动的元素,然后沿x轴将其包含元素的宽度滑动(如使用{{1}所示) }),而无需更改y轴。

这应该可以解决您的滑动问题,但是您将遇到另一个问题,需要弄清楚是否显示了滑块,或者您已经登录到网站。为此,您将需要一个Expected条件,该条件检查2个元素的存在:

  1. 滑块。
  2. 成功登录后希望看到的元素。

如果显示了您希望在登录时看到的元素,则无需执行任何操作。如果显示了滑块,则将需要执行上述逻辑,以使滑块滑过。

* 编辑 *

要对此进行更多改进,可以将滑动代码放入ExpectedCondition中,如下所示:

Perform sliding action

这将搜索您希望在登录时显示的元素。如果未显示您成功登录时希望看到的元素,则它将尝试找到滑块元素并进行交互与他们一起处理幻灯片验证。请注意,一旦尝试执行幻灯片验证,预期条件将返回False,这将强制其检查是否再次显示了预期的登录元素。

您可以像这样在代码中使用它:

slider_container.size['width']

上面的示例使用与上面相同的示例网站。要使其超时,可以将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 更改为不存在的内容。要使其通过而不滑动,您可以将# 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)) 修改为:

ELEMENT_TO_FIND

使用您在评论中提供的代码,我希望以下内容在aliexpress网站上起作用:

ELEMENT_TO_FIND

答案 1 :(得分:1)

尝试使用操作以下是c#代码供参考

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

按住滑杆后,尝试将其移至所需的偏移值

int x = 100; 
int y = 100;
Actions moveOffset = new Actions(driver);
moveOffset.MoveByOffset(x,y).Perform(); //set your suitable (x,y) offset value