如何通过 Java 使用 XPath 和 Selenium WebDriver 单击 SVG 元素

Posted

技术标签:

【中文标题】如何通过 Java 使用 XPath 和 Selenium WebDriver 单击 SVG 元素【英文标题】:How to click on SVG elements using XPath and Selenium WebDriver through Java 【发布时间】:2017-06-09 07:11:48 【问题描述】:

我有一个带有几个矩形元素的SVG 对象。使用geckodriver,我试图单击主要SVG 对象之一。但是使用 xpath-checker 我无法检测到正确的xpath

到目前为止,我可以通过 xpath 向下钻取:

id('avg_score_chart')/div/div[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg']

我的html代码如下:

<div id="avg_score_chart" class="chart" style="height: 250px; color: black ! important; overflow: hidden; text-align: left;">
<div class="amcharts-main-div" style="position: relative;">
<div class="amcharts-chart-div" style="overflow: hidden; position: relative; text-align: left; width: 525px; height: 212px; padding: 0px;">
<svg version="1.1" style="position: absolute; width: 525px; height: 212px; top: 0.450012px; left: -0.5px;">
<desc>javascript chart by amCharts 3.17.1</desc>
<g>
<g>
<g>
<g>
<g>
<g>
<g transform="translate(60,52)">
<g transform="translate(96,41)">
<g transform="translate(96,123)">
<g transform="translate(96,123)">
<path cs="100,100" d="M0.5,0.5 L0.5,-81.5 L30.5,-81.5 L30.5,0.5 L0.5,0.5 Z" fill="rgb(242,244,28)" stroke="rgb(242,244,28)" fill-opacity="0.8" stroke- stroke-opacity="0.8">
</g>
<g transform="translate(318,123)">
<g transform="translate(318,123)">
<g transform="translate(318,123)">
</g>
</g>
<g>
<g>
<g>
<g>
<g>
<g>
<g>
<g>
<g>
<g>
<g>
</svg>

谁能帮帮我?

【问题讨论】:

【参考方案1】:

尝试关注XPath,如果问题仍然存在,请告诉我:

//div[@id="avg_score_chart"]//*[name()="svg"]

对于&lt;g&gt; 元素:

//div[@id="avg_score_chart"]//*[name()="svg"]/*[name()="g"]

更新

最后,这应该是最好的选择:

//div[@class="portlet light boxshadow"][contains(.,"Store Wise Performance")]/div//div[@class="amcharts-chart-div"]/*[name()="svg"]//*[name()="g"]/*[name()="path" and @fill="rgb(242,244,28)"]

【讨论】:

这很奇怪......我原以为 SVG 标签可以像任何其他标签一样工作,例如//div[@id="avg_score_chart"]//svg。你知道为什么你必须使用name()吗? 对于一些标签(主要来自XMLDOM)需要使用/*[name()=tag_name]语法而不是常见的/tag_name...抱歉,不知道为什么会这样 @Dev,如果它解决了您的问题,请将此答案标记为“已接受”。谢谢 @Andersson,非常感谢您的宝贵建议。 1. 使用 xpath 作为:/div[@id="avg_score_chart"]//*[name()="svg"] 我可以(通过 xPathChecker)看到有 2 个元素的平均分数图表,我想点击第一个元素。 2. 使用xpath as: //div[@id="avg_score_chart"]//*[name()="svg"]/*[name()="g"] XPathChecker 找到18个元素,也就是总数页面上 SVG 元素的数量。但是我仍然不知道如何获取我粘贴了上面代码的元素的 xPath。 @Dev,如果页面上有几个svg 元素,您可以选择索引来选择第二个元素:(//div[@id="avg_score_chart"]//*[name()="svg"])[2]。告诉我你的目标元素是什么,因为你的问题不太清楚【参考方案2】:

怎么样: //div[@id='avg_score_chart']//*[local-name()='svg']/*[*[local-name()='path']]

您可以在 id 为 'avg_score_chart' 的 'div' 元素内的 'svg' 元素内找到任何具有 'path' 元素的元素。

编辑:将 xpath 放在代码块中

【讨论】:

感谢您的帮助。我已经尝试了这两个选项,但 xPathChecker 无法检测到元素并且 Eclipse 抛出异常: //div[@id='avg_score_chart']//[local-name()='svg']/[*[local-name( )='path']] 和 //div[@id='avg_score_chart']//[local-name()='svg']/[*[local-name()='path'][starts-with (@d, 'M371.75,174.28l')]] 你能进一步指导我吗? 等待一些字符丢失...可能被转义了。这是正确的://div[@id='avg_score_chart']//*[local-name()='svg']/*[*[local-name()='path']] 注意local-name()='svg'前面的星号和local-name()='path'前面的两个星号 非常感谢。我也试过 //div[@id='avg_score_chart']//*[local-name()='svg']/*[*[loca‌​l-name()='path']] 但 xPathChecker返回错误 & Eclipse 抛出异常。我已经更新了完整的 DOM。请你再看一遍好吗? //div[@id='avg_score_chart']//*[local-name()='svg']//*[*[loca‌​l-name()='path']]怎么样

以上是关于如何通过 Java 使用 XPath 和 Selenium WebDriver 单击 SVG 元素的主要内容,如果未能解决你的问题,请参考以下文章

通过 xpath 在 Python 中查找元素

HtmlAgilityPack XPath 错误

如何使用 XPath 和 Java 更新 XML

Java:如何通过 org.w3c.dom.document 上的 xpath 字符串定位元素

xpath学习,通过xpath 采集数据

如何通过移动 xpath 与 Appium 匹配 @text 属性和正则表达式(正则表达式)来查找元素?