【问题标题】:Selenium TimeoutException Error on clicking a button despite using EC.visibility_of_element_located().click() method?尽管使用了 EC.visibility_of_element_located().click() 方法,但单击按钮时出现 Selenium TimeoutException 错误?
【发布时间】:2022-03-19 10:37:19
【问题描述】:

我正在尝试使用 selenium python 在沃尔玛上创建一个帐户。我成功打开https://www.walmart.com/ 并成功转到登录标签下的创建帐户按钮。此外,我还成功输入了名字、姓氏、电子邮件地址和密码的详细信息。然而,一旦我点击了 Create account button,尽管使用了 EC.visibility_of_element_located().click,我还是得到了 TimeoutException 错误() 方法。

谁能指导我我的方法有什么问题。提前致谢。

创建账号按钮的网站源码如下:

<button class="button m-margin-top text-inherit" type="submit" data-automation-id="signup-submit-btn" data-tl-id="signup-submit-btn" aria-label="Create Account, By clicking Create Account, the user is acknowledging that they have read and agreed to the Terms of Use and Privacy Policy">Create account</button>

我的Python代码如下:

import time
import requests
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains

url = "https://www.walmart.com/"

first_name = "chuza"
last_name = "123"
email_id = "chuza123@gmail.com"
password = "Eureka1@"

options = Options()
s=Service('C:/Users/Samiullah/.wdm/drivers/chromedriver/win32/96.0.4664.45/chromedriver.exe')
driver = webdriver.Chrome(service=s, options=options)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source":
        "const newProto = navigator.__proto__;"
        "delete newProto.webdriver;"
        "navigator.__proto__ = newProto;"
})
wait = WebDriverWait(driver, 20)
actions = ActionChains(driver)
driver.get(url)
sign_in_btn = wait.until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Sign In']")))
actions.move_to_element(sign_in_btn).perform()
time.sleep(0.5)
wait.until(EC.visibility_of_element_located((By.XPATH, '//button[normalize-space()="Create an account"]'))).click()

f_name = driver.find_element(By.ID, 'first-name-su')
l_name = driver.find_element(By.ID, 'last-name-su')
email = driver.find_element(By.ID, 'email-su')  
pswd = driver.find_element(By.ID, 'password-su')
f_name.send_keys(first_name)
driver.implicitly_wait(2)
l_name.send_keys(last_name)
driver.implicitly_wait(1.5)
email.send_keys(email_id)
driver.implicitly_wait(2)
pswd.send_keys(password)
driver.implicitly_wait(0.5)
### 
wait.until(EC.visibility_of_element_located((By.XPATH, '//button[normalize-space()="Create account"]'))).click()

【问题讨论】:

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


    【解决方案1】:

    我看到这个代表所需 web 元素的 css 选择器:

    button[data-automation-id='signup-submit-btn']
    

    xpath 将是:

    //button[@data-automation-id='signup-submit-btn']
    

    每个 CSS 和 XPath 有 3 个匹配节点,Selenium 会寻找第一个匹配,CSS 和 XPath 基本上是第一个匹配节点。

    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-automation-id='signup-submit-btn']"))).click()
    

    wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-automation-id='signup-submit-btn']"))).click()
    

    在尝试单击 Web 元素时使用 element_to_be_clickable 而不是 visibility_of_element_located 更有意义。此外,与 XPath 相比,CSS 是更好的定位器。

    【讨论】:

      【解决方案2】:

      //button[normalize-space()="Create account"] 定位器匹配该页面上的 3 个元素,您需要使用更精确的定位器。
      这个定位器是独一无二的://form[@id='sign-up-form']//button[@data-tl-id='signup-submit-btn']
      所以,这应该工作:

      wait.until(EC.visibility_of_element_located((By.XPATH, "//form[@id='sign-up-form']//button[@data-tl-id='signup-submit-btn']"))).click()
      

      【讨论】:

        【解决方案3】:

        这个 xpath 基于 Locator Strategy...

        //button[normalize-space()="Create account"]
        

        ...标识DOM Tree 中的三(3) 个元素,您想要的元素是列表中的第二个。


        解决方案

        所需元素是动态元素,因此要单击 clickable 元素而不是 visibility_of_element_located(),您需要为 element_to_be_clickable() 诱导 WebDriverWait,然后您可以使用以下Locator Strategy

        • 使用XPATH

          WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//form[@id='sign-up-form']//button[normalize-space()='Create account']"))).click()
          
        • 注意:您必须添加以下导入:

          from selenium.webdriver.support.ui import WebDriverWait
          from selenium.webdriver.common.by import By
          from selenium.webdriver.support import expected_conditions as EC
          

        【讨论】:

          【解决方案4】:

          这个问题是因为 selenium,你可以通过手动创建来解决这个问题,按照以下步骤操作:

          点击搜索框前的人形图标,在沃尔玛 IO 平台 here 上创建一个帐户。

          登录帐户并接受“使用条款”

          单击“创建您的应用程序”以创建一个新应用程序并填写适当的详细信息。

          您可以关注this tutorial生成两组公钥/私钥,一组用于生产,另一组用于舞台。

          使用这个上传两个公钥:https://walmart.io/key-upload?app_name=&lt;your app name&gt;

          将为 prod 和 stage 的两个集合生成消费者 ID,可在 dashboard 上查看

          点击here 的 OPD API 的“请求访问”并填写表格

          【讨论】:

            猜你喜欢
            • 2022-01-01
            • 2020-01-08
            • 1970-01-01
            • 1970-01-01
            • 2021-06-29
            • 1970-01-01
            • 2017-06-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多