【问题标题】:Select all anchor tags with an href attribute that contains one of multiple values via xpath in lxml / Python通过lxml / Python中的xpath选择具有href属性的所有锚标记,该属性包含多个值之一
【发布时间】:2013-08-01 07:23:24
【问题描述】:

我需要自动扫描大量 html 文档以查找被锚标记包围的广告横幅,例如:

<a href="http://ad_network.com/abc.html">
    <img src="ad_banner.jpg">
</a>

作为 xpath 的新手,我可以通过 lxml 选择这样的锚点,如下所示:

text = '''
    <a href="http://ad_network.com/abc.html">
        <img src="ad_banner.jpg">
    </a>'''

root = lxml.html.fromstring(text)
print root.xpath('//a[contains(@href,("ad_network.")) or contains(@href,("other_ad_network."))][descendant::img]')

在示例中,我检查了两个不同的域:“ad_network”。和“其他广告网络”。但是,有超过 25 个域需要检查,通过“或”连接所有这些包含指令,xpath 表达式会变得非常长。而且我担心这种表达方式在 CPU 资源方面效率很低。是否有一些语法可以检查多个“包含”值?

我也可以通过正则表达式在一行代码中获取相关链接。然而,尽管 html 代码已被 lxml 规范化,但 regex 似乎从来都不是这种工作的好选择......感谢任何帮助!

【问题讨论】:

    标签: python xpath operators lxml contains


    【解决方案1】:

    仅仅做一堆'或'可能没那么糟糕。用 python 构建 xpath,这样你就不会遇到 writer 的抽筋,然后预编译它。实际的 xpath 代码在 libxml 中,应该很快。

    sites=['aaa', 'bbb']
    contains = ' or '.join('contains(@href,(%s))' % site for site in sites)
    anchor_xpath = etree.XPath('//a[%s][descendant::img]' % contains)
    

    【讨论】:

    • 我喜欢这种方法......我只是在等着看是否有更短/更有效的解决方案,然后再接受它。你知道什么更快:在 html 文档上使用一个正则表达式还是这个相当长的 xpath?
    • @Nasmon - 我的直觉是正则表达式会更快一些,但我参与过使用大量 xpath 的项目,而且它们运行良好。这都可能是过早优化的情况。正则表达式 html 文档是有问题的 - 你想坚持使用 xml 解析器 - 但在 xpath 中使用正则表达式是可以的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多