【问题标题】:Confirm preceding and following sibling in XPATH在 XPATH 中确认前后同级
【发布时间】:2021-10-04 02:04:00
【问题描述】:

我有以下语句来检查是否存在 2 个条件 一个元素:

 if len(driver.find_elements(By.XPATH, "//span[text()='$400.00']/../following-sibling::div/a[text()='Buy']")) > 0:
   elem = driver.find_element(By.XPATH, "//span[text()='$400.00']/../following-sibling::div/a[text()='Buy']")

我尝试了一些变体,包括“preceding sibling::span[text()='x'”,但似乎无法使语法正确,或者我的方法是否正确。

HTML 如下。当前的 find_elements(By.XPATH...) 正确找到了“Total”和“Buy”类,我还想在“price”类中添加 20.00 美元作为条件。

    <ul>
       <li class="List">
           <div class="List-Content row">
               <div class="Price">"$20.00"</div>
               <div class="Quantity">10</div>
               <div class="Change">0%</div>
               <div class="Total">
                   <span>$400.00</span>
               </div>
               <div class="Buy">
                   <a class="Button">Buy</a>
               </div>
           </div>
        </li>
    </ul>

【问题讨论】:

  • 分享网址。如果不可能,请使用 HTML 代码更新问题。
  • 需要查看 HTML 以进一步帮助您。
  • 已更新 HTML。谢谢!
  • 我还想在“价格”类中添加 20.00 美元作为条件。 - 你能解释一下吗?
  • 一般性评论:text() 并没有做您显然认为的事情。不要使用它来按文本内容搜索元素。请改用.(例如span[. = '$400.00']a[. = 'Buy'])或直接使用该元素(例如//*[span = '$400.00']/following-sibling::div/...)。

标签: python selenium


【解决方案1】:

使用内置的 ElementTree

import xml.etree.ElementTree as ET


html = '''<li class="List">
   <div class="List-Content row">
       <div class="Price">"$20.00"</div>
       <div class="Quantity">10</div>
       <div class="Change">0%</div>
       <div class="Total"><span>$400.00</span></div>
       <div class="Buy"><a class="Button">Buy</a></div>
   </div>
   <div class="List-Content row">
       <div class="Price">"$27.00"</div>
       <div class="Quantity">10</div>
       <div class="Change">0%</div>
       <div class="Total"><span>$400.00</span></div>
       <div class="Buy"><a class="Button">Buy</a></div>
   </div>
</li>'''

items = {'Total':'$400.00','Buy':'Buy','Price':'"$20.00"'}

root = ET.fromstring(html)
first_level_divs = root.findall('div')
for first_level_div in first_level_divs:
    results = {}
    for k,v in items.items():
        div = first_level_div.find(f'.div[@class="{k}"]')
        one_level_down = len(list(div)) > 0
        results[k] = list(div)[0].text if one_level_down else div.text
    if results == items:
        print('found')
    else:
        print('not found')
    results = {}

输出

found
not found 

【讨论】:

    【解决方案2】:

    鉴于这个 HTML sn-p

    <ul>
       <li class="List">
           <div class="List-Content row">
               <div class="Price">"$20.00"</div>
               <div class="Quantity">10</div>
               <div class="Change">0%</div>
               <div class="Total"><span>$400.00</span></div>
               <div class="Buy"><a class="Button">Buy</a></div>
           </div>
        </li>
    </ul>
    

    我会使用这个 XPath:

    buy_buttons = driver.find_elements(By.XPATH, """//div[
        contains(@class, 'List-Content')
        and div[@class = 'Price'] = '$20.00'
        and div[@class = 'Total'] = '$400.00'
    ]//a[. = 'Buy']""")
    
    for buy_button in buy_buttons:
       print(buy_button)
    

    for 循环替换您的 if len(buy_buttons) &gt; 0 检查。没有结果时不会运行,所以if是多余的。

    【讨论】:

    • 干杯 Tomalak - 有什么理由有“””引号?他们应该是 cmets 吗?
    • @user1345331 不,它们不是 cmets。它们是多行字符串。它们被用作 cmets 只是一个约定,这里我使用它们来增加 XPath 语句的可读性。
    • 好的,谢谢!代码正在运行,但没有返回我所期望的。如果我取出循环并打印buy_buttons,它会返回“[]”......有什么想法吗?我的 HTML 上有几个缩进,我已经更新了这些缩进,但我认为这不会影响它。
    • @user1345331 如果您必须在比较之前修剪元素文本,请使用normalize-space(),例如and normalize-space(div[@class = 'Total']) = '$400.00'.
    猜你喜欢
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多