如何从JS的available_dates变量获取日期并传入Python脚本?
问题描述
我需要获取日期选择器中的可用日期,这些日期会被存储在填充HTML输入框的JS脚本的available_dates变量中。输入框的HTML代码如下:
<input type="text" readonly="" class="form-control-input app_date validate" style="width: 260px;" id="app_date" name="app_date" placeholder="YYYY-MM-DD" onchange="this.form.submit();showLoader();" value="" autocomplete="off">
我尝试用以下Python脚本获取可用日期并选择,但无法正常工作:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException driver.find_element(By.XPATH, "//*[@id='app_date']").click() time.sleep(3) try: print([date.get_attribute("innerHTML") for date in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class='datepicker-days']/table[@class=' table-condensed']//tr//td[@class='day activeClass' and @title='Book']")))]) except TimeoutException: print("No booking dates available for the current month") driver.refresh()
对应的JS脚本中,available_dates变量及日期判断逻辑关键片段如下:
var available_dates = []; function formatDate(rawDate) { var day = ("0" + rawDate.getDate()).slice(-2); var month = ("0" + (rawDate.getMonth() + 1)).slice(-2); return (day)+ "-" + (month)+ "-" +rawDate.getFullYear() ; } $('.app_date').datepicker({ language: "en", format: "yyyy-mm-dd", startDate: new Date('2023-02-15'), endDate: '2023-02-28', autoclose: true, beforeShowDay: function(date){ var formattedDate = formatDate(date); if ($.inArray(formattedDate.toString(), available_dates) != -1){ return { enabled : true, classes: 'activeClass', tooltip: 'Book' }; } // 其他日期禁用逻辑... } });
解决方案
可以通过两种方式获取available_dates中的值并在Python脚本中使用:
方法1:直接执行JavaScript提取available_dates
Selenium允许直接在浏览器中执行JS代码,可直接获取available_dates数组的内容,无需通过DOM元素定位:
# 确保页面JS已加载完成 available_dates = driver.execute_script("return available_dates;") print("可用日期列表:", available_dates) # 若有可用日期,转换格式后填入输入框并提交 if available_dates: # JS中日期格式为DD-MM-YYYY,需转为输入框要求的YYYY-MM-DD day, month, year = available_dates[0].split("-") formatted_date = f"{year}-{month}-{day}" # 设置输入框值 date_input = driver.find_element(By.ID, "app_date") date_input.clear() date_input.send_keys(formatted_date) # 触发onchange事件提交表单 driver.execute_script("document.getElementById('app_date').dispatchEvent(new Event('change'));") else: print("没有可用日期")
方法2:修复原Selenium定位逻辑
如果一定要通过DOM元素获取可用日期,需优化定位表达式并使用显式等待替代固定延时:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException # 显式等待输入框可点击并打开日期选择器 date_input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "app_date"))) date_input.click() # 等待日期面板加载并定位可用日期 try: # 使用contains匹配class,避免空格导致的匹配失败 available_date_elements = WebDriverWait(driver, 20).until( EC.visibility_of_all_elements_located( (By.XPATH, "//div[contains(@class, 'datepicker-days')]/table[contains(@class, 'table-condensed')]//td[contains(@class, 'day activeClass') and @title='Book']") ) ) # 获取日期文本(仅为日,需结合年月补全格式) available_dates = [elem.text for elem in available_date_elements] print("当前月可用日期:", available_dates) # 点击第一个可用日期 if available_date_elements: available_date_elements[0].click() except TimeoutException: print("当前月没有可预订日期")
内容的提问来源于stack exchange,提问作者Elouali Issam
相关产品推荐
相关产品推荐

