如何使用LXML中的XPATH基于其属性指定特定元素

时间:2012-12-20 23:43:46

标签: python html lxml

我正在努力提高对XPATH的理解。我有一个包含许多元素的文档。我在文档中寻找具有某些特定文本的粗体字体元素。

这是div元素中的字体元素的示例。 font元素包含我想要捕获的粗体文本

<div style="line-height:120%;padding-bottom:10px;padding-top:10px;font-size:10pt;"><font style="font-family:inherit;font-size:10pt;font-weight:bold;">SECTION 1.&nbsp;&nbsp;&nbsp;&nbsp;Executive&nbsp;Summary</font></div>

让我明白这是一份更大的文件的一部分。我找到了一个XPATH教程,它描述了如何选择特定元素

只是为了确保我没有遇到我正在阅读文件的问题

tree=html.fromstring(open('c:\\mytest.htm')

x=tree.xpath('//font') 

这有效,因为x有3023个元素,当我检查它们时,我发现它们都是字体元素。有些是我想要的元素。

然后我尝试使用

隔离相关元素
my_elements = tree.xpath('//font[@font-weight='bold']')

这不起作用,因为my_elements是空的。在写这个问题时,我仔细看了一下html的剪辑,并在IDLE中玩了一些。我认为问题是我没有字体标签font-weight的属性。字体权重与样式属性相关。此示例中字体标记的唯一属性是样式。我想说更多但恐怕我会把水弄得太多了

底线我希望能够使用xpath查找所有粗体的字体元素,并在文本中包含单词部分我可以通过迭代元素并以非常笨重的方式进行测试

my_elements = [e for e in tree.iter() if e.tag == 'font' if 'bold' in e.values()[0] ]
my_elements = e for e in my_elements if 'section' in e.text_content().lower()

XPATH看起来很值得理解。

感谢您的任何解释。

哼哼我终于走在了正确的轨道上

testelem=tree.xpath('//font[contains(@style,"font-weight:bold")]')

好的,现在我们使用和运算符

testelem=tree.xpath('//font[contains(@style,"font-weight:bold") and contains(text(),"SECTION")]')

现在让它不区分大小写

我已经接近了解如何包含工作,但我很高兴有人提出解决方案

testelem=tree.xpath('//font[contains(@style,"font-weight:bold") and starts-with(translate(text(),"SECTION","section"),"section")]')

1 个答案:

答案 0 :(得分:3)

只是意识到这篇文章就像&gt; 2岁,无论如何,我仍然希望这个答案可以帮助那些提出这个问题的人。

您可以在 lxml 的xpath中使用regular expression。默认情况下,XPath支持EXSLT命名空间中的正则表达式:

testelem = tree.xpath('//font[re:match(text(), \
                      "^(?i)section.*") and \
                      contains(@style, "font-weight:bold")]',
                      namespaces={'re': "http://exslt.org/regular-expressions"})

print testelem
[<Element font at 0x1042f49f0>]

for t in testelem:
    print t.text, t.attrib

SECTION 1.    Executive Summary {'style': 'font-family:inherit;font-size:10pt;font-weight:bold;'}