代码之家  ›  专栏  ›  技术社区  ›  William DeVries

Python Selenium向字段问题发送密钥

  •  0
  • William DeVries  · 技术社区  · 2 年前

    我刚开始使用python的selenium模型,在尝试自动化该商店的结账过程时遇到了一个问题, https://bellevo.store/products/luna . 我让python点击立即购买并填写信息,它运行良好,直到进入城市领域。我不认为它是可点击的,我也不知道为什么。如有任何帮助,我们将不胜感激。这是我的代码

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import time
    
    # Initialize a new browser instance
    driver = webdriver.Chrome()
    
    # Click "Buy It Now"
            wait = WebDriverWait(driver, 10)
            buy_now_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"product form-template--22164028883241__main\"]/div/div/dynamic-checkout")))
            buy_now_button.click()
    
    # Fill in contact and delivery fields
    wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"email\"]"))).send_keys(phone_number)
    time.sleep(.5)
    wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"TextField0\"]"))).send_keys(first_name)
    time.sleep(.5)
    wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"TextField1\"]"))).send_keys(last_name)
    time.sleep(.5)
    wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id=\"billing-address1\"]"))).send_keys(address + ", " + city + ", " + state + ", USA")
    time.sleep(.5)
    wait.until(EC.element_to_be_clickable((By.XPATH, "//label[@id=\"TextField6-label\"]"))).send_keys(city)
    

    我尝试了很多不同的方法,但都没能找到解决方案。正如我所说,我是硒的新手,可能对硒没有很好的了解。

    1 回复  |  直到 2 年前
        1
  •  0
  •   JeffC    2 年前

    你很接近。您的代码实际上相当不错。下面我有一些改进建议。

    这可能是一个艰难的场景。我认为你遇到的问题是,你试图在“城市”字段中键入内容,但当时不可见,因为地址建议下拉列表是打开的。有几种方法可以解决这个问题。。。

    1. 按照您的方法,手动填写所有字段(地址、城市、州、邮编)。要做到这一点,您必须关闭地址建议下拉列表,以便填写城市、州、邮编。如果你走这条路,你只需要将地址发送到地址字段,因为你没有使用地址建议下拉列表。城市、州和zip将进入各自的领域。
    2. 使用自动建议列表并选择第一个选项,该选项应与您输入的完整地址相匹配。

    我选择了#2。我还清理了一些东西。。。

    1. 如果您正在使用ID,请使用 By.ID() 而不是 By.XPATH() .

    2. 我删除了 time.sleep() s.你不需要它们,因为你有适当的等待时间。你有 WebDriverWait s这很好。。。最好的做法是使用它们并避免 time.sleep() .

    3. 将来,如果您有嵌套的双引号( " ),用单引号替换( ' ),例如更改 "//*[@id=\"email\"]" "//*[@id='email']" 。它使阅读更容易,并删除了转义字符。

    4. 如果要单击某个元素,请使用 EC.element_to_be_clickable() 。如果要以其他方式与元素交互,例如send_keys(),请使用 EC.visibility_of_element_located() 避免 EC.presence_of_element_located() 在大多数情况下。。。它只是确认元素在DOM中,而不是它是可见的或可以被点击。我看到很多人使用它,然后点击等元素。。。这只是在问一些难以追踪的间歇性问题。

    5. 你不必,但我更喜欢 f 连接字符串的字符串文字。我发现它们更容易阅读和使用。不再确保匹配 " s每次插入新变量时,等等。请参阅 the docs 了解更多信息。

      s = address + ", " + city + ", " + state + ", USA"
      

      变成

      s = f"{address}, {city}, {state}, USA"
      

    考虑到我的所有建议,下面是清理后的代码,正在运行。

    from selenium import webdriver
    from selenium.webdriver import Keys
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    # Initialize a new browser instance
    url = 'https://bellevo.store/products/luna'
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get(url)
    
    wait = WebDriverWait(driver, 10)
    
    # Click "Buy It Now"
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.shopify-payment-button__button"))).click()
    
    # Fill in contact and delivery fields
    wait.until(EC.element_to_be_clickable((By.ID, "email"))).send_keys(phone_number)
    wait.until(EC.element_to_be_clickable((By.ID, "TextField0"))).send_keys(first_name)
    wait.until(EC.element_to_be_clickable((By.ID, "TextField1"))).send_keys(last_name)
    e = wait.until(EC.visibility_of_element_located((By.ID, "billing-address1")))
    e.send_keys(f"{address}, {city}, {state}, USA")
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#billing-address1-options > li"))).click()
    e.send_keys(Keys.ENTER)