lxml - 在findall()中使用正则表达式按属性值查找标签

时间:2012-06-02 17:24:40

标签: python html lxml

我正在尝试使用lxml来获取格式为

的注释数组
<div id="comment-1">
  TEXT
</div>

<div id="comment-2">
  TEXT
</div>

<div id="comment-3">
  TEXT
</div>
...

我尝试使用

html.findall(".//div[@id='comment-*']")

但这会搜索文字星号。

我正在尝试做什么是正确的语法?

编辑:我终于通过

开始工作了
doc = lxml.html.parse(url).getroot()
comment_array = doc.xpath('.//div[starts-with(@id, "comment-")]')

3 个答案:

答案 0 :(得分:1)

您可以使用regular XPath functions按照建议查找评论:

comments = doc.xpath('.//div[starts-with(@id, "comment-")]')

但是,对于更复杂的匹配,您可以使用正则表达式:对于lxml,XPath支持EXSLT命名空间中的正则表达式。请参阅官方文档Regular expressions in XPath

这是一个演示:

from lxml import etree

content = """\
<body>
<div id="comment-1">
  TEXT
</div>

<div id="comment-2">
  TEXT
</div>

<div id="comment-3">
  TEXT
</div>

<div id="note-4">
  not matched
</div>
</body>
"""

doc = etree.XML(content)

# You must give the namespace to use EXSLT RegEx
REGEX_NS = "http://exslt.org/regular-expressions"

comments = doc.xpath(r'.//div[re:test(@id, "^comment-\d+$")]',
                          namespaces={'re': REGEX_NS})

要查看结果,您可以“转储”匹配的节点:

for comment in comments:
    print("---")
    etree.dump(comment)

你得到:

---
<div id="comment-1">
      TEXT
    </div>


---
<div id="comment-2">
      TEXT
    </div>


---
<div id="comment-3">
      TEXT
    </div>

答案 1 :(得分:0)

html.findall中的path部分仅允许XPath subset用作表达式,默认情况下不使用正则表达式。

为此,您必须使用here所述的EXSLT扩展程序 - 或者您可以使用xpath core functions

答案 2 :(得分:0)

我有类似的愿望并做了一些事情,虽然我并不为此感到非常自豪,但还是完成了工作。

def node_checker(node):
    if node.attrib['id'].find('hurf-durf') > -1:
        return True
    else:
        return False


for node in itertools.ifilter(node_checker, r.iterdescendants(tag='sometag')):
    print node.tag

这不是我最好的工作,但它让我足够接近getElementById,并且有一些灵活性,我可以转移到另一个问题。