【问题标题】:Selecting elements at the same node选择同一节点的元素
【发布时间】:2019-05-21 11:31:00
【问题描述】:

我正在用 Python 编写 Selenium 自动化脚本。作为一个过程,我需要收集一些元素。下面是示例 html(我进行了编辑以使其看起来很简单)。当我执行搜索时,我得到类似于下面的搜索结果。

现在,我需要餐厅中的元素列表并执行一些操作。酒吧、购物、咖啡也是如此。

事情是lh和li处于同一节点级别。

我尝试了以下 xpath,但它只选择 lh 元素

//ul[@id='searchresults']//ancestor::lh

我也经历了有用的Concept XML XLST preceding-sibling and ancestor。但是,还没有想出解决办法

示例 html 代码:

<ul id="searchresults">
    <lh style="">Restaurants</lh>
    <li title="Chamber"><span>Chamber</span></li>
    <li title="Chillies"><span>Chillies</span></li>
    <li title="Sushi Ville"><span>Sushi Ville</span></li>
    <li title="Toasters"><span>Toasters</span></li>
    <li title="Joe Grills"><span>Joe Grills</span></li>
    <lh style="">Bars</lh>
    <li title="Y Cocktails"><span>Y Cocktails</span></li>
    <li title="Z Brewery"><span>Z Brewery</span></li>
    <li title="X Drinks"><span>X Drinks</span></li>
    <lh style="">Shopping</lh>
    <li title="Pacific"><span>Pacific</span></li>
    <li title="Spencers"><span>Spencers</span></li>
    <li title="Hays"><span>Hays</span></li>
    <lh style="">Coffee</lh>
    <li title="Roasters"><span>Roasters</span></li>
    <li title="Coffee Beans"><span>Coffee Beans</span></li>
    <li title="Coffee Cafe"><span>Coffee Cafe</span></li>
</ul>

非常感谢您的帮助,如果我缺少或需要任何有助于解决此问题的信息,请告诉我。

【问题讨论】:

  • lh 标签是什么?
  • @EthanK 我认为它代表 List Header。
  • 这是 HTML 代码吗?
  • 哦,原来如此。您知道它应该只直接跟随ulol 吗? source
  • @EthanK 老实说,我不知道。我试图在这里复制与我项目中的网页大部分相同的代码。

标签: python css selenium selenium-webdriver xpath


【解决方案1】:

您可以执行以下操作:

  • 遍历“列表标题”元素
  • 对于每个“列表标题”,​​获取以下兄弟姐妹并收集“标签”(我们将这些 li 元素文本命名为“标签”)直到遇到 lh 兄弟姐妹李>

类似的东西:

for lh in driver.find_elements_by_xpath("//ul[@id='searchresults']//lh"):
    restaurant = lh.text

    tags = []
    for element in lh.find_elements_by_xpath("./following-sibling::*"):
        if element.tag_name == 'lh':
            break

        tags.append(element.text)

    print(restaurant, tags)

【讨论】:

  • 你的解决方案就像一个魅力。我只是复制粘贴。 :)
  • @JackSuze 不错!确保接受答案以解决该主题。谢谢!
【解决方案2】:

我通过在会话中运行一些 javascript 来为以下每个列表项 (LI) 添加一个带有列表标题 (LH) 名称的自定义属性,您需要更改自定义属性名称在不与当前属性冲突的情况下满足您的需求。

my_js = """let currentLh;
document.querySelectorAll(arguments[0]).forEach(function (elem) {
    if (elem.tagName === "LH") {
        currentLh = elem.textContent.toLowerCase();
    } else {
        elem.setAttribute("my-custom-attr", currentLh);
    }
"""

driver.execute_script(my_js, 'ul#searchresults > *')
my_restaurant_list = driver.find_elemets_by_css_selector('li[my-custom-attr="restaurant"]')
my_bar_list = driver.find_elemets_by_css_selector('li[my-custom-attr="bars"]')
my_shopping_list = driver.find_elemets_by_css_selector('li[my-custom-attr="shopping"]')
my_coffee_list = driver.find_elemets_by_css_selector('li[my-custom-attr="coffee"]')

这使用了 JS NodeList.forEach 函数,可能并非在所有浏览器中都可用,如果您在那里发现问题,您将不得不为无序列表中的所有元素找到更便携的循环解决方案。

【讨论】:

  • 不知何故我现在不想使用 js。但是,很高兴知道我可以这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
相关资源
最近更新 更多