【问题标题】:Why does a function in nested XPATH conditional cause the error?为什么嵌套 XPATH 条件中的函数会导致错误?
【发布时间】:2020-06-17 19:19:52
【问题描述】:

这是关于从 webDrv.find_elements_by_xpath() 调用收到的“xpath 表达式无效”错误的问题。

背景

在招聘网站上搜索包含目标职位文本的元素时,例如“scrum master”(标准化为 lower()),在诸如

的元素中找到
<a href="/jobs/view/1836192833/">
    Scrum MASTER
</a>

Selenium-Python 查询...

aJobTitle = getNormalJobTitle(...) # to match "scrum master" with "Scrum Master" "SCRUM Master" etcA s = '// *[contains(translate(text(),"ABCDEFGHIJKLMNOPURSTUWXYZ", "abcdefghijklmnopurstuwxyz"), "' + aJobTitle + '")]' jobNodes = webDrv.find_elements_by_xpath(s)

完美运行。所有“Scrum MASTER”、“Scrum Master”、“Scrum master”等元素都返回了。

但是,当网站(无论出于何种原因)包含其他元素时,例如,

&lt;a href="/jobs/view/1836192833/"&gt; Scrum Master &lt;!----&gt; &lt;/a&gt;

上面的查询什么也没找到。

使用不同的 xpath 形式——并且在没有 lower() 规范化的情况下工作...

s = "//*[text()[contains(.,'" + "Scrum MASTER" + "')]]" jobNodes = webDrv.find_elements_by_xpath(s)

完美运行。所有且仅返回“Scrum MASTER”元素(当然,不包括“Scrum Master”等)

我的问题

但是,当我尝试使用标准化的小写职位名称进行搜索时,将调用 text() 替换为调用 translate(text(),,)...

aJobTitle = getNormalJobTitle(...) # "scrum master" s = "//*[translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')[contains(.,'" + aJobTitle + "')]]"

我很高兴

Exception has occurred: InvalidSelectorException Message: Given xpath expression "//*[translate(tex(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')[contains(.,'scrum master')]]" is invalid: [Exception... "<no message>" nsresult: "0x80600008 (<unknown>)" location: "JS frame :: chrome://marionette/content/element.js :: element.findByXPathAll :: line 410" data: no] File "C:myfile.py JS.py", line 41, in <module> jn = liJobsElement.find_elements_by_xpath(s)

所以最后...

1) 为什么添加函数会导致错误?
2) 我如何实现规范化,以便我可以找到所有案例形式,例如职位?

【问题讨论】:

  • 错误信息包含tex() - 应该是text()
  • 嗯。在繁重的写作和排版任务中,我一定是打了个“t”;我在 stackoverflow 板上的第一次格式化工作。谢谢!好眼力!只需在 VSCode 调试器中重新运行它:selenium.common.exceptions.InvalidSelectorException: Message: Given xpath expression "//*[translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')[contains(.,'scrum master' )]]" 无效:[异常..."" nsresult:"0x80600008 ()" location:"JS frame :: chrome://marionette/content/element.js :: element. findByXPathAll :: line 410" 数据:无]
  • 错误消息中引用的表达式是合法的 XPath,即使在 XPath 1.0 中也是如此。
  • 我们到了。

标签: python-3.x selenium-webdriver xpath


【解决方案1】:

你写:translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')[

您不能将谓词与字符串一起使用(即:translate 函数的输出)。这就是您的 XPath 无效的原因。可以测试的是元素、属性和text() 节点。

关于您的问题,您的第一个 XPath 对我来说看起来不错。但是一些 XPath 引擎不认为它有效。工作 XPath 可能是:

使用normalize-space 函数(我们删除contains 函数):

//*[translate(normalize-space(),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="scrum master"]

使用上下文项.(而不是有问题的text()),但我们必须指定元素名称(a)或添加谓词(无子元素):

//a[contains(translate(.,"ABCDEFGHIJKLMNOPURSTUWXYZ", "abcdefghijklmnopurstuwxyz"),"scrum master")]

//*[contains(translate(.,"ABCDEFGHIJKLMNOPURSTUWXYZ", "abcdefghijklmnopurstuwxyz"),"scrum master")][count(./*)=0]

所以,总而言之,你可以使用类似的东西:

s = '//*[translate(normalize-space(),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="%s"]'%str(aJobTitle)
jobNodes = webDrv.find_elements_by_xpath(s)

s = '//a[contains(translate(.,"ABCDEFGHIJKLMNOPURSTUWXYZ", "abcdefghijklmnopurstuwxyz"),"%s")]'%str(aJobTitle)
jobNodes = webDrv.find_elements_by_xpath(s)

s = '//*[contains(translate(.,"ABCDEFGHIJKLMNOPURSTUWXYZ", "abcdefghijklmnopurstuwxyz"),"%s")][count(./*)=0]'%str(aJobTitle)
jobNodes = webDrv.find_elements_by_xpath(s)

【讨论】:

  • 太棒了,E!倒数第二个和最后一个表格成功了!非常神秘的解决方案;在我的所有搜索中都没有看到 normalize-space() 。将尝试了解该功能。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多