我正在编写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输出(表明querySelector
和evaluate
都没有问题)
> 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*)
(**)
答案 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
就足够了,并且得到相同的结果。