如何使用Python Selenium点击g标签内的path元素(附代码求修复)
修复后的铁路购票自动化脚本
前置准备
- 在项目目录下创建
form_data.txt文件,写入以下内容:
Mark Couwell Erkek 29 07 1988 Pasport I-AG 266556
修复后的完整代码
import time from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC class Project: def __init__(self) -> None: self.driver = webdriver.Chrome() self.main() def find_the_place_path(self): # 获取所有path标签,定位指定座位 all_place_in_path = self.driver.find_elements(By.TAG_NAME, "path") for place in all_place_in_path: title = place.get_attribute('title') print(title) if title == "gat: 3": print("已进入gat:3座位区域") WebDriverWait(self.driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//*[name()='path' and @title='gat: 3']")) ).click() time.sleep(2) break def find_the_place_rect(self): # 获取所有rect标签,定位指定座位 all_place_in_rect = self.driver.find_elements(By.TAG_NAME, "rect") for place in all_place_in_rect: title = place.get_attribute('title') print(title) if title == "gat: 2": print("已进入gat:2座位区域") btn = self.driver.find_element(By.XPATH, "//*[name()='rect' and @title='gat: 2']") btn.click() break elif title == "gat: 3": print("检测到gat:3座位") def input_data(self): # 读取form_data.txt中的用户信息 with open("form_data.txt","r", encoding="utf-8") as data: line = data.readline().strip() if line: words = line.split() first_name = words[0] last_name = words[1] gender = words[2] bday = words[3] bmoth = words[4] byear = words[5] document_type = words[6] document_snumber = words[7] document_number = words[8] time.sleep(3) # 填写手机号 self.driver.find_element(By.ID, "phone").send_keys('61260799') # 选择性别 jyns = Select(self.driver.find_element(By.ID, "jyns")) jyns.select_by_visible_text(gender) # 填写姓名 self.driver.find_element(By.ID, 'lastname').send_keys(last_name) self.driver.find_element(By.ID, 'name').send_keys(first_name) # 填写邮箱 self.driver.find_element(By.ID, "email").send_keys("welbekowallanur@gmail.com") # 选择证件类型 passport = Select(self.driver.find_element(By.ID, "passport")) passport.select_by_visible_text(document_type) # 等待证件区域加载并选择证件地区 WebDriverWait(self.driver, 5).until( EC.presence_of_element_located((By.CLASS_NAME, 'passport_code_b')) ) pass_region = self.driver.find_element(By.CSS_SELECTOR, 'div.first > div.slide > div.info_r > div.wrap > ul > li > div > div.passport_code_b > div:nth-child(1)' ) passport_region = Select(pass_region.find_element(By.ID, "passport")) passport_region.select_by_visible_text(document_snumber) # 填写证件号码 self.driver.find_element(By.ID, 'code').send_keys(document_number) # 选择出生日期 day = Select(self.driver.find_element(By.ID, "bday")) day.select_by_visible_text(bday) month = Select(self.driver.find_element(By.ID, "bmonth")) month.select_by_visible_text(f"{bmoth} - Iýul") year = Select(self.driver.find_element(By.ID, "byear")) year.select_by_visible_text(byear) # 尝试填写疫苗信息 try: self.driver.find_element(By.ID, "kepilnama").send_keys("321") except: print("未找到疫苗信息输入框") # 点击选择座位按钮 time.sleep(2) choose_place_btn = self.driver.find_element(By.XPATH, "/html/body/div[4]/div[3]/div[4]/div/button") choose_place_btn.click() time.sleep(2) # 定位座位 self.find_the_place_path() # self.payment() def main(self): # 打开官网并最大化窗口 self.driver.get("https://railway.gov.tm/") self.driver.maximize_window() # 选择出发地 from_select = Select(self.driver.find_element(By.ID, "one_way")) from_select.select_by_visible_text("Aşgabat") # 选择目的地 to_select = Select(self.driver.find_element(By.ID, "two_way")) to_select.select_by_visible_text("Daşoguz") # 设置出发日期 self.driver.execute_script("document.getElementById('search_date').setAttribute('data-value', '2022-07-29');") time.sleep(1) # 点击搜索按钮 btn = self.driver.find_element(By.XPATH, "/html/body/div[4]/div[2]/div/div/div/div/a") btn.click() time.sleep(2) # 检查可用车票 self.check_ticken() def check_ticken(self): # 查找可用座位 li_elements = self.driver.find_elements(By.TAG_NAME, "li") for li in li_elements: class_name = li.get_attribute('class').strip() print(f"检测到座位类名:{class_name}") if class_name == "seat_1": print("找到可用座位,开始选择") li.click() self.input_data() break elif class_name == "seat_": print("当前无可用座位,重新刷新页面尝试") self.driver.refresh() time.sleep(2) self.main() break def payment(self): # 模拟支付信息填写 card_number = "9931020202020202" card_holder = "ALLANUR WELBEKOW" cvc = "999" self.driver.find_element(By.XPATH, "//*[@id='pan_visible']").send_keys(card_number) # 选择月份 d_month_select = Select(self.driver.find_element(By.ID, "month")) d_month_select.select_by_visible_text("Июль") # 选择年份 d_year_select = Select(self.driver.find_element(By.ID, "year")) d_year_select.select_by_visible_text("2035") # 填写持卡人姓名和CVC self.driver.find_element(By.XPATH, "//*[@id='iTEXT']").send_keys(card_holder) self.driver.find_element(By.XPATH, "//*[@id='iCVC']").send_keys(cvc) if __name__=="__main__": pr = Project()
主要修复点
- 类方法缩进错误:原代码中
main()、find_the_place_path()等方法未缩进,不属于Project类,已修正为类成员方法。 - 过时API替换:将
find_elements_by_tag_name()、find_element_by_id()等旧方法替换为Selenium 4.x支持的find_elements(By.TAG_NAME, ...)写法。 - 文件操作优化:使用
with语句自动管理文件资源,避免文件未关闭的问题,同时添加编码声明确保读取特殊字符正常。 - 座位定位逻辑修正:修改
find_the_place_path()中的XPATH,直接通过@title属性定位目标座位,避免无效路径匹配;修正Java风格的driver.findElement为Python的driver.find_element。 - 类名判断优化:在
check_ticken()中对获取的class名进行strip()处理,避免多余空格导致匹配失败。 - 支付模块错误修复:修正
payment()中误将d_year_select使用d_month_select调用方法的错误。 - 冗余导入清理:移除
ast、asyncio等无用导入模块,精简代码结构。 - 代码可读性提升:添加中文注释,拆分长表达式,统一变量命名风格。
内容的提问来源于stack exchange,提问作者Allanur1999
相关产品推荐
相关产品推荐

