你很接近。您的代码实际上相当不错。下面我有一些改进建议。
这可能是一个艰难的场景。我认为你遇到的问题是,你试图在“城市”字段中键入内容,但当时不可见,因为地址建议下拉列表是打开的。有几种方法可以解决这个问题。。。
-
按照您的方法,手动填写所有字段(地址、城市、州、邮编)。要做到这一点,您必须关闭地址建议下拉列表,以便填写城市、州、邮编。如果你走这条路,你只需要将地址发送到地址字段,因为你没有使用地址建议下拉列表。城市、州和zip将进入各自的领域。
-
使用自动建议列表并选择第一个选项,该选项应与您输入的完整地址相匹配。
我选择了#2。我还清理了一些东西。。。
-
如果您正在使用ID,请使用
By.ID()
而不是
By.XPATH()
.
-
我删除了
time.sleep()
s.你不需要它们,因为你有适当的等待时间。你有
WebDriverWait
s这很好。。。最好的做法是使用它们并避免
time.sleep()
.
-
将来,如果您有嵌套的双引号(
"
),用单引号替换(
'
),例如更改
"//*[@id=\"email\"]"
到
"//*[@id='email']"
。它使阅读更容易,并删除了转义字符。
-
如果要单击某个元素,请使用
EC.element_to_be_clickable()
。如果要以其他方式与元素交互,例如send_keys(),请使用
EC.visibility_of_element_located()
避免
EC.presence_of_element_located()
在大多数情况下。。。它只是确认元素在DOM中,而不是它是可见的或可以被点击。我看到很多人使用它,然后点击等元素。。。这只是在问一些难以追踪的间歇性问题。
-
你不必,但我更喜欢
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)