我需要使用 Selenium 提取表格内的 html 文本。我没有可以使用的唯一类、id 或其他标识符。线条看起来像这样。我需要“成本要素”文本。
<th align="LEFT" bgcolor="7DA6CF" width="350 px" overflow="HIDDEN"> Cost Elements</th>
这是完整的 html 块。
<tr>
<th align="LEFT" bgcolor="7DA6CF" width="350 px" overflow="HIDDEN"> Cost Elements</th>
<th align="CENTER" bgcolor="7DA6CF" width="160 px" overflow="HIDDEN"> Plan</th>
<th align="CENTER" bgcolor="7DA6CF" width="160 px" overflow="HIDDEN"> Period 6</th>
<th align="CENTER" bgcolor="7DA6CF" width="160 px" overflow="HIDDEN"> Cumulative Act.
</th>
<th align="CENTER" bgcolor="7DA6CF" width="160 px" overflow="HIDDEN"> Commitments</th>
<th align="CENTER" bgcolor="7DA6CF" width="160 px" overflow="HIDDEN"> $ Variance</th>
<th align="CENTER" bgcolor="7DA6CF" width="90 px " overflow="HIDDEN"> % Remain</th>
</tr>
这是我的代码,如果有帮助的话。 Table1_cols 是我尝试提取表列名称的地方。
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
service = Service(executable_path = 'C:\Program Files\edgedriver_win64\msedgedriver.exe')
driver = webdriver.Edge(service=service)
driver.get('C:\\Users\\User\\Downloads\\_SAPreport-behnke r-20240102.HTM_.HTM')
ne_mesonet_table = driver.find_element(By.LINK_TEXT, "Nebraska Mesonet")
ne_mesonet_table.click()
ne_mesonet_xpath1 = '//html//body//table[1]//tbody'
table1 = driver.find_element(By.XPATH, ne_mesonet_xpath1)
table1_rows = table1.find_elements(By.TAG_NAME, "tr")
table1_cols = table1_rows[0].find_elements(By.TAG_NAME, 'th')
因此,您正在尝试从某个列收集一些数据,但该列不存在唯一属性。
如果您100%确定表格不会改变,您可以使用固定数字,例如//table/tbody/tr/td[5] 为第五列。但从实践来看,你永远无法 100% 确定:)
更正确的方法是迭代所有列以找到所需的索引。 请参阅此基于 the-internet.herokuapp.com 的示例:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
wait = WebDriverWait(driver, 5)
try:
driver.get("https://the-internet.herokuapp.com/tables")
# find a column
table_headers = wait.until(EC.visibility_of_all_elements_located((By.XPATH, "//table[@id='table1']/thead//th")))
target_column = "Email"
for i, header in enumerate(table_headers):
if header.text == target_column:
column_index = i + 1
break
else:
raise RuntimeError(f"Target column '{target_column}' is not found in the table.")
# collect data
table_rows = wait.until(EC.visibility_of_all_elements_located((By.XPATH, "//table[@id='table1']/tbody/tr")))
all_emails = []
for row in table_rows:
column = row.find_element(By.XPATH, f"./td[{column_index}]")
all_emails.append(column.text)
print(f"All '{target_column}' collected: {all_emails}")
finally:
driver.quit()
在此示例中,将收集所有行中的“电子邮件”值。
如果需要收集表中的所有数据,可以创建一个字典列表(key=header, value=./td[header_index].text)