【问题标题】:XPATH partial match tr id with Python, Selenium,XPATH 部分匹配 tr id 与 Python、Selenium、
【发布时间】:2019-02-27 06:39:14
【问题描述】:

能否请我使用正确的 XPATH 来提取 tr id="review_" 元素? 我设法获得了元素,但幸运的是 ID,因为它们是部分匹配

<table class="admin">
<thead>"snip"</thead>
<tbody>
    <tr id="review_984669" class="">
    <td>weird_wild_and_wonderful_mammals</td>
    <td>1</td>
    <td><input type="checkbox" name="book_review[approved]" id="approved" value="1" class="attribute_toggle"></td>
    <td><input type="checkbox" name="book_review[rejected]" id="rejected" value="1" class="attribute_toggle"></td>
    <td>February 27, 2019 03:56</td>
    <td><a href="/admin/new_book_reviews/984669?page=2">Show</a></td>
    <td>
        <span class="rest-in-place" data-attribute="review" data-object="book_review" data-url="/admin/new_book_reviews/984669">
bad
        </span>
    </td>
    </tr>
    <tr id="review_984670" class="striped">

我使用 Selenium 和 Chrome 来提取页面上唯一的表格。

Table_Selenium_Elements = driver.find_element_by_xpath('//*[@id="admin"]/table')

然后我使用下面的方法从每一行获取数据。

for Pri_Key, element in enumerate(Table_Selenium_Elements.find_elements_by_xpath('.//tr')):
# Create an empty secondary dict for each new Pri Key
    sec = {}
    # Secondary dictionary needs a Key. Keys are items in column_headers list
    for counter, Sec_Key in enumerate(column_headers):
        # Secondary dictionary needs Values for each key.
        # Values are individual items in each sub-list of column_data list
        # Slice the sub list with the counter to get each item
        sec[Sec_Key] = element.get_attribute('innerHTML')[counter]
    pri[Pri_Key] = sec

这只是显示每个ie中的数据 "weird_wild_and_wonderful_mammals", "1"

但我实际上也需要 tr id=review_xxx。我不知道该怎么做。 id 编号发生了变化,因此可能是 xpath 'contains' 表达式或 xpath 'begins_with' 表达式。

由于我是菜鸟,我想我已经捕获了 review_ID,但我没有通过我的 for 循环正确提取。

谁能告诉我正确的 XPATH 来提取父 tr 和子 tds。 ...然后我将调整我的 for 循环。 谢谢 山姆

【问题讨论】:

  • 你能分享完整的 html 和你的代码或分享 url 吗?
  • @DaftVader 你指的是哪些元素tr id="review_" elements

标签: python-3.x selenium xpath


【解决方案1】:

根据您的 html 和下面的选择器示例,您可以获得所有行:

admin_table_rows = driver.find_elements_by_css_selector(".admin tbody > tr")
admin_table_rows = driver.find_elements_by_css_selector(".admin tr[id^='review_']")
admin_table_rows = driver.find_elements_by_xpath("//table[@class='admin']//tr[starts-with(@id,'review_')]")

要获取id 属性,您可以使用element.get_attribute("id") 方法。

这里是如何抓取数据的示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)

admin_table_rows = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".admin tr[id^='review_']")))

for row in admin_table_rows:
    row_id = row.get_attribute("id").replace("review_", "")
    label = row.find_element_by_css_selector("td:nth-child(1)")
    num = row.find_element_by_css_selector("td:nth-child(2)")
    date = row.find_element_by_css_selector("td:nth-child(3)")
    href = row.find_element_by_css_selector("a").get_attribute("href")

【讨论】:

  • Sers,你是最棒的。这行得通。非常感谢 :) 您发现了我的问题,以非常清晰的方式提出了您的答案,并给了我一些替代方案 - 一些阅读表明 xpath 很脆弱。
【解决方案2】:

您只是要求一个 xPath 来定位表格元素本身吗?

在您的示例中,您有一个 xPath 来查找您拥有的表

[@id="admin"]

'admin' 是类,而不是 id。如果您只是将其切换为

是否有效
Table_Selenium_Elements = driver.find_element_by_xpath('//*[@id="admin"]/table')

【讨论】:

  • 不,我有表格,但我没有从中得到正确的数据。我想我只得到了 td 信息,而不是 tr 和 td 信息。 @Sers 答案没有修改我的表格提取代码。相反,Sers 展示了从表格中取出数据的更好方法:row.get_attribute("id").replace("review_", "" **row.find_element_by_css_selector("td:nth-child(1)")
【解决方案3】:
driver.find_element_by_class_name('striped')

# If it is the last row in the table.
driver.find_elements_by_css_selector('tbody tr')[-1]

# If it is surely the 2nd row in the table.
driver.find_elements_by_css_selector('tbody tr')[1]

【讨论】:

  • 抱歉,根据我的原始代码,这些行有不同的类
猜你喜欢
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2016-03-23
相关资源
最近更新 更多