通过lxml / Python中的xpath选择href属性包含多个值之一的所有锚标记

时间:2013-07-31 16:31:33

标签: python xpath operators lxml contains

我需要为锚标记包围的广告横幅自动扫描大量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”。和“other_ad_network。”。但是,有超过25个域需要检查,并且通过“或”连接所有这些conatains-directives,xpath表达式将变得非常长。而且我担心这种表达在CPU资源方面会非常低效。是否有一些语法可以检查多个“包含”值?

我也可以通过一行代码中的正则表达式来获取相关链接。然而,尽管html代码是通过lxml标准化的,但正则表达式似乎永远不会成为这类工作的好选择......任何帮助都会受到赞赏!

1 个答案:

答案 0 :(得分: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)