【问题标题】:lxml - using regex in findall() to find tags by attribute valueslxml - 在 findall() 中使用正则表达式按属性值查找标签
【发布时间】:2012-06-07 12:43:00
【问题描述】:

我正在尝试使用 lxml 来获取格式为的 cmets 数组

<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-")]')

【问题讨论】:

  • 试试html.findall(".//div[starts-with(@id,'comment-')")

标签: python html lxml


【解决方案1】:

您可以按照您的建议使用regular XPath functions 查找 cmets:

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>

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我有类似的愿望,做了一些我并不十分自豪的事情,但完成了工作。

      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 并具有一定的灵活性,我能够继续解决另一个问题。

      【讨论】:

        猜你喜欢
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-21
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        相关资源
        最近更新 更多