如何在XPath查询中从前一个属性值提取嵌入的属性值?

3 投票
3 回答
2283 浏览
提问于 2025-04-16 20:41

我正在尝试从以下这段HTML中“选择”onclick属性里的链接

<span onclick="Javascript:document.quickFindForm.action='/blah_blah'" 
 class="specialLinkType"><img src="blah"></span>

但是我只能做到下面这个XPath

//span[@class="specialLinkType"]/@onclick

这个XPath只返回了

Javascript:document.quickFindForm.action

有没有什么办法可以用XPath提取quickFindForm.action里面的那个链接呢?

3 个回答

0

如果Scrapy支持XPath字符串函数,这样就可以用了。

substring-before(
   substring-after(
      //span[@class="specialLinkType"]/@onclick,"quickFindForm.action='")
   ,"'")

看起来它也支持正则表达式。像这样的写法应该可以。

.select('//span[@class="specialLinkType"]/@onclick').re(r'quickFindForm.action=\'(.*?)\'')

注意:我不能测试第二个解决方案,你需要确认一下在这种情况下\'是否是单引号的正确转义方式。

0

我使用了xquery,但在xpath中应该也是一样的。我用了一个叫“tokenize”的xpath函数,它可以根据一个规则把字符串分开(你可以在这个链接找到更多信息:http://www.xqueryfunctions.com/xq/fn_tokenize.html)。在这个例子中,我是根据“ ' ”来分割字符串的。

        xquery version "1.0";
        let $x := //span[@class="specialLinkType"]/@onclick
        let $c := fn:tokenize( $x, '''' )
        return $c[2]

在xpath中应该是这样的:

        fn:tokenize(//span[@class="specialLinkType"]/@onclick, '''' )[2]
1

我在一个Java应用程序中试了XPath,结果还不错:

    import java.io.IOException;
    import java.io.StringReader;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathExpression;
    import javax.xml.xpath.XPathFactory;

    import org.w3c.dom.Document;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;

    public class Teste {

        public static void main(String[] args) throws Exception {
            Document doc = stringToDom("<span onclick=\"Javascript:document.quickFindForm.action='/blah_blah'\" class=\"specialLinkType\"><img src=\"blah\"/></span>");
            XPath newXPath = XPathFactory.newInstance().newXPath();
            XPathExpression xpathExpr = newXPath.compile("//span[@class=\"specialLinkType\"]/@onclick");
            String result = xpathExpr.evaluate(doc);
            System.out.println(result);

        }

        public static Document stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.parse(new InputSource(new StringReader(xmlSource)));
        }
    }

结果:

Javascript:document.quickFindForm.action='/blah_blah'

撰写回答