Python Selenium 输入框发送按键问题

0 投票
1 回答
20 浏览
提问于 2025-04-13 00:13

我刚开始使用Python的Selenium库,想要自动化这个商店的结账流程,网址是https://bellevo.store/products/luna。我已经写了代码,可以点击“立即购买”并填写信息,一切都很顺利,直到要填写城市这一栏。我觉得它没有把城市字段识别为可以点击的,我也不太明白为什么。希望能得到一些帮助。这是我的代码:

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)

我尝试了很多不同的方法,但还是找不到解决办法。正如我所说,我对Selenium还不太熟悉,可能理解得不够透彻。

1 个回答

0

你做得很不错,代码写得也很好。我有一些建议可以让它更好。

这个情况可能有点棘手。我觉得你遇到的问题是,你在填写城市字段时,那个字段看不见,因为地址建议的下拉框打开了。有几种方法可以解决这个问题……

  1. 你可以按照自己的方法,手动填写所有字段(地址、城市、州、邮政编码)。这样的话,你需要先关闭地址建议的下拉框,才能填写城市、州和邮政编码。如果选择这个方法,你只需要把地址填到地址字段里,因为你不使用地址建议下拉框。城市、州和邮政编码就填到各自的字段里。
  2. 使用自动建议列表,选择第一个选项,这个选项应该和你输入的完整地址匹配。

我选择了第二种方法。我还整理了一些内容……

  1. 如果你使用的是ID,建议用 By.ID(),而不是 By.XPATH()

  2. 我去掉了 time.sleep()。你不需要它们,因为你已经有了合适的等待时间。你使用了 WebDriverWait,这很好……使用它们是最佳实践,避免使用 time.sleep()

  3. 将来如果你有嵌套的双引号("),可以用单引号(')交替使用,比如把 "//*[@id=\"email\"]" 改成 "//*[@id='email']"。这样更容易阅读,也去掉了转义字符。

  4. 如果你要点击一个元素,使用 EC.element_to_be_clickable()。如果你要与元素进行其他交互,比如发送键值,使用 EC.visibility_of_element_located()。大多数情况下避免使用 EC.presence_of_element_located()……它只是确认元素在DOM中,而不是确认它可见或可以点击。我看到很多人使用这个,然后再去点击元素……这样容易导致一些难以追踪的问题。

  5. 虽然不是必须的,但我更喜欢用 f 字符串来拼接字符串。我觉得这样更容易阅读和使用。这样就不需要每次插入新变量时都确保引号匹配了。想了解更多,可以查看 文档

    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)

撰写回答