ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 XPath 通过 CSS 类查找元素?

在我的网页中,有一个 div 和一个名为 Testclass

如何使用 XPath 找到它?

更通用的相关 XPath、CSS、DOM 和 Selenium 解决方案可以在文档 XPath, CSS, DOM and Selenium: The Rosetta Stone 中找到。具体来说,您的答案可以在项目 Id &名称

T
Teemu Leisti

这个选择器应该可以工作,但如果你用合适的标记替换它会更有效:

//*[contains(@class, 'Test')]

或者,因为我们知道寻找的元素是 div

//div[contains(@class, 'Test')]

但由于这也将匹配 class="Testvalue"class="newTest" 之类的情况,@Tomalak 在评论中提供的版本更好

//div[contains(concat(' ', @class, ' '), ' Test ')]

如果您希望确定它会正确匹配,您还可以使用 normalize-space 函数来清除类名周围的杂散空白字符(如@Terry 所述):

//div[contains(concat(' ', normalize-space(@class), ' '), ' Test ')]

请注意,在所有这些版本中,最好将 * 替换为您实际希望匹配的任何元素名称,除非您希望在文档中搜索给定条件的每个元素。


@meder:更像 //div[contains(concat(' ', @class, ' '), ' Test ')] - 你的也会出现部分匹配。
你为什么不直接做 //div[@class='Test']
因为类可以包含多个值
我很惊讶 xpath 没有快捷方式/更有效的方法来在空格分隔的标记列表中定位标记。 xpath 的更高版本中有什么吗?
@thomasrutter 为什么会感到惊讶 - 这只是一种为 XML 制作的语言,而不是更具体的 HTML,谁说使用空格分隔的列表作为 XML 中的任何节点值是随意的。 Tomalak 的解决方案是一个非常可行的解决方案。
W
Will Tate

最简单的方法。。

//div[@class="Test"]

假设您想按照描述找到 <div class="Test">


上面的语法更容易使用并且不易出错。请记住,您需要在班级周围加上双引号才能进行搜索。我建议使用上面列出的。 //div[@class="测试"]
@Jake0x32,那是因为它使用 // 而不仅仅是 /
它是否也匹配`
@JugalThakkar 不,不是。它需要完全匹配才能工作,但您可以尝试 //div[contains(@class,"Test")] 代替。
这个答案可能会受益于进一步的澄清,因为它并没有真正回答 OP 的问题。 OP 说“一个名为 Test 的类的 div”,但绝不建议“Test”是 div 中唯一的类,这是这个答案所假设的。这个答案的简单性很吸引人,这可能会引诱读者陷入困境。
J
John Slegers

使用 XPath 的唯一正确方法是:

//div[contains(concat(" ", normalize-space(@class), " "), " Test ")]

函数 normalize-space 去除前导和尾随空格,并将空白字符序列替换为单个空格。

笔记

如果不需要很多这些 Xpath 查询,您可能希望使用将 CSS 选择器转换为 XPath 的库,因为 CSS 选择器通常比 XPath 查询更容易读写。例如,在这种情况下,您可以使用选择器 div.Test 来获得完全相同的结果。

我能够找到的一些图书馆:

对于 JavaScript:css2xpath 和 css-to-xpath

对于 PHP:CssSelector 组件

对于 Python:cssselect

对于 C#:重新加载 css2xpath

对于 GO:css2xpath


这确实是避免问题的唯一方法,例如,如果您分配了多个班级!
//div[@class[contains(.,'Test')]] 怎么样?
A
Alex Lyman

我只是提供这个作为答案,正如托马拉克很久以前作为对 meder 的回答的评论所提供的那样

//div[contains(concat(' ', @class, ' '), ' Test ')]

很抱歉从这么久以前提出这个问题,但是 concat(' ', normalize-space(@class), ' ') 又如何考虑各种空白字符呢?
出于好奇 - 为什么 //div[contains(concat(' ', @class, ' '), ' Test ')]/chid 不选择子项?
@Fusion如果您将其作为问题发布,您可能会得到答案。
@bitolean 现在很难成为 Cbvious 队长
@Fusion我只是想帮忙。 XPath 不是 HTML 感知语言。它更通用,仅限 XML。我没有任何经验,但我认为你假设你可以只放 id 而不是标签。您需要选择“id”属性的值。因此,您需要将 HTML 文档视为 XML。不过,离题的讨论并不能帮助人们找到解决方案。
B
Bennett McElwee

XPath 有一个 contains-token 函数,specifically designed 适用于这种情况:

//div[contains-token(@class, 'Test')]

它仅在最新版本的 XPath (3.1) 中受支持,因此您需要最新的实现。


XPath 3.1,根据您的链接。
是的,它是在 3.1 版中添加的。 W3C 有一个不错的 3.0-3.1 diff。我已经更新了答案。
S
Siebe Jongebloed

由于 XPath 2.0 有一个标记化功能,您可以使用:

//div[tokenize(@class,'\s+')='Test']

在这里,它将在空白处进行标记,然后将生成的字符串与“测试”进行比较。

它是 XPath 3.1 函数 contains-token() 的替代方案

但是目前(2021-04-30)没有浏览器支持 XPath 2.0 或更高版本。


u
user31782
//div[@class[contains(.,'Test')]]

这就是我在我目前的项目中使用的,它工作顺利。

表达式中的点 . 表示任何 div 元素的 class 属性的值。所以您不需要使用 normalize-spaceconcat。请注意,这也可能会选择类名 XXXTestXXX 的 div。我碰巧将我的可搜索类设置为 infobox-header,并且该页面没有类似 XXinfobox-headerXXXX 的任何内容。


P
Philip

匹配一个有空格的类。

<div class="hello "></div>
//div[normalize-space(@class)="hello"]