我在创建一个自动结账过程的程序时遇到了一些麻烦。我正在使用python 3和Selenium。该程序解析一系列日期,这些日期在页面上输出为可用的四个可用插槽。如果当前页面上没有可用的,它将单击"下一步"按钮并搜索接下来的四个日期。如果它到达可用日期范围的末尾,却一无所获,它将等待30秒,然后重置并重新进行。
我已经完成了大部分工作,除了两个问题:
1( 我试图添加一个参数,当包含该参数时,它将超越基本功能(即简单地使用Twilio通过文本通知用户(,并完成完整的结账过程。
这是我正在使用的python代码:
def find_available(args):
dates_available = True
spaces_free = False
free_spaces = ""
while not spaces_free:
while dates_available:
time.sleep(1.5)
spots = driver.find_elements_by_css_selector('.ss-carousel-item')
for spot_index, spot in zip(range(date_range), spots):
if spot.value_of_css_property('display') != 'none':
spot.click()
available_dates = driver.find_elements_by_css_selector('.Date-slot-container')
for available_date in available_dates:
if available_date.value_of_css_property('display') != 'none':
selected_spot = available_date.find_element_by_css_selector('#slot-container-UNATTENDED')
if 'No doorstep delivery' not in selected_spot.text:
free_spaces = selected_spot.text.replace('Select a time', '').strip()
spaces_free = True
else:
print(selected_spot.text.replace('Select a time', '').strip())
if spaces_free:
print('Slots Available!')
if args.checkout:
client.messages.create(to=to_mobilenumber,
from_=from_mobilenumber,
body=free_spaces)
driver.find_element_by_xpath("//*[contains(text(), 'Soonest available')]").click()
time.sleep(1.5)
driver.find_element_by_xpath("//input[@type='submit' and @value='Continue']").click()
print('Your order has been placed!')
else:
client.messages.create(to=to_mobilenumber,
from_=from_mobilenumber,
body=free_spaces)
print('Your order time will be held for the next hour. Check your date and confirm!')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="auto-checkout")
parser.add_argument('--checkout', '-c', action='store_true',
help="Select first available slot and checkout")
args = parser.parse_args()
find_available(args)
预期行为
如果程序是使用"--checkout"或"-c"参数启动的,那么,一旦"spaces free"设置为true,它就应该发送一个包含"free_spaces"元素内文本的文本。然后,它应该进入下一阶段,即选择包含文本"最早可用"的单选按钮(如选择包含可用时隙的第一个可用单选按钮(,然后单击继续按钮。
实际行为
该程序将运行,找到一个可用的时间段,然后简单地进入下一天,永远不会尝试选择单选按钮并在结账过程中继续前进。
我做错了什么?
如有任何帮助,我们将不胜感激。
在我看来,您从未在while
循环中将dates_available
设置为False
:
while dates_available:
time.sleep(1.5)
spots = driver.find_elements_by_css_selector('.ss-carousel-item')
for spot_index, spot in zip(range(date_range), spots):
if spot.value_of_css_property('display') != 'none':
spot.click()
available_dates = driver.find_elements_by_css_selector('.Date-slot-container')
for available_date in available_dates:
if available_date.value_of_css_property('display') != 'none':
selected_spot = available_date.find_element_by_css_selector('#slot-container-UNATTENDED')
if 'No doorstep delivery' not in selected_spot.text:
free_spaces = selected_spot.text.replace('Select a time', '').strip()
spaces_free = True
else:
print(selected_spot.text.replace('Select a time', '').strip())
因此,您永远不会退出while
循环。如果您不想重写整个逻辑,可以在设置spaces_free = True
之后立即设置dates_available = False
。这将允许退出while
循环,但您可能也需要一个或两个break
才能退出for
循环。
如果你想要一个故障保护行为,你应该为更小的函数重构你的代码,如果你只想要第一个可用的东西,你可以只从具有第一个可用数据的函数中提取return
。
也许是这样的?
def find_available(args):
def get_a_date():
while True:
time.sleep(1.5)
spots = driver.find_elements_by_css_selector('.ss-carousel-item')
for spot_index, spot in zip(range(date_range), spots):
if spot.value_of_css_property('display') != 'none':
spot.click()
available_dates = driver.find_elements_by_css_selector('.Date-slot-container')
for available_date in available_dates:
if available_date.value_of_css_property('display') != 'none':
selected_spot = available_date.find_element_by_css_selector('#slot-container-UNATTENDED')
if 'No doorstep delivery' not in selected_spot.text:
return selected_spot.text.replace('Select a time', '').strip()
else:
print(selected_spot.text.replace('Select a time', '').strip())
free_spaces = get_a_date()
print('Slots Available!')
if args.checkout:
client.messages.create(to=to_mobilenumber,
from_=from_mobilenumber,
body=free_spaces)
driver.find_element_by_xpath("//*[contains(text(), 'Soonest available')]").click()
time.sleep(1.5)
driver.find_element_by_xpath("//input[@type='submit' and @value='Continue']").click()
print('Your order has been placed!')
else:
client.messages.create(to=to_mobilenumber,
from_=from_mobilenumber,
body=free_spaces)
print('Your order time will be held for the next hour. Check your date and confirm!')