使用lxml查找属性值而不使用for循环

时间:2014-08-18 16:08:22

标签: python python-2.7 lxml

这是我目前的代码:

>>>p = []
>>>r = root.findall('.//*div/[@class="countdown closed"]/')
>>>r
'<abbr data-utime="1383624000" class="timestamp"/>'
>>>for i in r:
            s = i.attrib
            p.append(s['data-utime'])
>>>p
['1383624000']

s产量:

{'class': 'timestamp', 'data-utime': '1383624000'}

我认为上面的代码很冗长(创建一个列表,只使用for循环的1个字符串)。

我知道lxml能够更简洁地实现这一目标但是我无法实现这一点,我感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

使用XPath,而不是ElementTree findall()(这是一种更有限且受限制的语言,用于与ElementTree库lxml扩展兼容),并将您的路径一直指向属性:

root.xpath('//html:div[@class="countdown closed"]/@data-utime',
  namespaces={'html': 'http://www.w3.org/1999/xhtml'})

可能在XPath中使用命名空间通配符,但不是很好的做法 - 它不仅会使命中空间冲突开放,而且如果您的引擎对其进行索引,也可能是性能障碍完全限定的属性名称。)

答案 1 :(得分:1)

如果您希望只找到一个元素,请使用.find(),而不是.findall()

r = root.find('.//*div/[@class="countdown closed"]/')
if r is not None:
    p.append(r['data-utime'])
如果找不到匹配项,

element.find()会返回None或元素。如果您确定元素始终存在,则可以省略if r is not None测试。

因为您正在使用lxml,所以您可以使用element.xpath() method来使用更强大的XPath表达式,这些表达式仅仅是ElementTree方法可以支持的。您可以在路径中添加/@attribute-name attribute selection element以直接选择属性值

attr = root.xpath('.//*div[@class="countdown closed"]/@data-utime')
p.extend(attr)

.xpath()也会返回一个列表,但您只需使用p.extend一步即可将所有包含的值添加到p