使用Python和Selenium点击表格中动态变化的预订按钮问题
Got it, let's break this down. The biggest mistake here would be relying on the button's dynamic name or its position in the table (since that shifts based on available rooms). Instead, we need to tie the button directly to the "Room 34" text it's associated with in the table structure.
Core Approach
We'll use XPath to first locate the element that displays "Room 34", then traverse the DOM to find the corresponding booking button in the same table row (or container). This works no matter where the room moves in the table.
Step-by-Step Implementation
1. Basic XPath Locator (Same Table Row)
Most booking tables structure each room as a separate <tr> (table row) with one <td> for the room number and another for the booking button. Use this XPath to target the button in the same row as "Room 34":
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("your_booking_website_url") # Locate the button by first finding Room 34's cell, then moving up to the row and finding the button room_34_button = driver.find_element(By.XPATH, "//td[text()='Room 34']/parent::tr//button") room_34_button.click()
2. Handle Text Spacing or Partial Matches
If the room number has extra spaces (like " Room 34 "), use normalize-space() to clean up the text:
room_34_button = driver.find_element(By.XPATH, "//td[normalize-space(text())='Room 34']/parent::tr//button")
Or if the room number is part of longer text (like "Room 34 - King Bed"), use contains():
room_34_button = driver.find_element(By.XPATH, "//td[contains(text(), 'Room 34')]/parent::tr//button")
3. Add Wait for Element Load (Critical!)
To avoid "element not found" errors due to slow page loading, use WebDriverWait to wait until the button is clickable:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # Wait up to 10 seconds for the button to be ready room_34_button = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//td[normalize-space(text())='Room 34']/parent::tr//button")) ) room_34_button.click()
4. Adjust for Unique Button Attributes
If the button has a specific class or attribute (like class="book-room-btn"), add that to the XPath to make it more precise:
room_34_button = driver.find_element(By.XPATH, "//td[normalize-space(text())='Room 34']/parent::tr//button[@class='book-room-btn']")
Why This Works
By linking the button to the static "Room 34" text, we completely bypass the dynamic button name and shifting table positions. The XPath will always find the button associated with that room, no matter how the table rearranges itself.
内容的提问来源于stack exchange,提问作者JRrcgp

