document.evaluate JavaScript在AppleScript中未返回任何内容

时间:2019-04-19 11:02:06

标签: javascript xpath applescript

我正在编写AppleScript脚本以在Safari中抓取网页,并且有一段我一直在苦苦挣扎。

这将返回所需的文本:log (do JavaScript "document.querySelector('h1 > span').innerHTML;" in front document)

这不是:log (do JavaScript "document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;" in front document)

在浏览器检查器中,两种方法都有效,但是在AppleScript中,xpath的任何变体对我而言都无效。

我真的需要使用document.evaluate函数在同一脚本中执行类似document.evaluate("//p[contains(., 'Metrics')]/following-sibling::p[1]/text()[normalize-space()]", document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;的操作。

必须如何重写才能在AppleScript中开始产生结果?


示例HTML代码:

<html>
<body>
  <h1>
    <span>Test Entry</span>
  </h1>
</body>
</html>

Safari Web Inspector输出(表明querySelectorevaluate都没有问题)

> document.querySelector('h1 > span').innerHTML;
< "Test Entry"
> document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
< "Test Entry"

AppleScript编辑器代码:

tell application "Safari"
  log (do JavaScript "document.querySelector('h1 > span').innerHTML;" in front document)
  log (do JavaScript "document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;" in front document)
end tell

AppleScript编辑器输出(表明querySelector有效而evaluate不可用):

(*Test Entry*)
(**)

1 个答案:

答案 0 :(得分:1)

您用于最小样本(content-type: application/json; charset=UTF-8)的XPath表达式在浏览器DOM中选择一个文本节点,并且使用//h1/span/text()[normalize-space()]时,您的Javascript代码将返回该文本节点(https://dom.spec.whatwg.org/#text )。然后,浏览器的专门检查器可能会直接显示文本节点的内容,但看起来您的AppleScript控制台没有执行该操作。

如果您希望Javascript代码返回带有文本节点值的纯字符串,则可以使用文本节点的document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue属性(https://dom.spec.whatwg.org/#dom-characterdata-data),就像您使用{{1}通过data调用获得的元素节点的}属性。

所以

innerHTML

在Javascript中返回DOM文本节点,要获取包含文本节点内容的字符串,请使用querySelector属性,例如。

document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue

另一种选择是使用

data

您需要一个最小的示例,请注意,只要您使用以document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.data document.evaluate('//h1/span/text()[normalize-space()]', document.body, null, XPathResult.STRING_TYPE, null).stringValue 开头的绝对XPath,使用/作为//的第二个参数,仅传递document.body就足够了,并且得到相同的结果。