解析XML字符串
网页下载下来以后是字符串的形式,使用etree.fromstring(str)
构造一个etree._ElementTree
对象,使用etree.tostring(t)
返回一个字符串
from lxml import etree
xml_string='<root><foo id="foo-id" class="foo zoo">Foo</foo><bar>中文</bar><baz></baz></root>'
root=etree.fromstring(xml_string)
print etree.tostring(root)
# <root><foo id="foo-id" class="foo zoo">Foo</foo><bar>中文</bar><baz/></root>
print etree.tostring(root,pretty_print=True)
#没有子节点的baz变成了自闭和的标签
"""
<root>
<foo id="foo-id" class="foo zoo">Foo</foo>
<bar>中文</bar>
<baz/>
</root>
"""
print type(root)
#tostring返回的是一个_Element类型的对象,也使整个xml树的根结点
# <type 'lxml.etree._Element'>
Element结构
etree._Element是一个设计很精妙的结构,可以把它当作一个对象访问当前节点自身的文本节点,可以把它当作一个叔祖,元素就是他的子节点,可以把它当作一个字典,从而遍历它的属性:
foo=root[0]
result={}
for attr,val in foo.items():
result[attr]=val
print result
# {'id': 'foo-id', 'class': 'foo zoo'}
#获取foo标签中id对应的值
print foo.get('id')
# foo-id
#foo标签的属性
print foo.attrib
# {'id': 'foo-id', 'class': 'foo zoo'}
Element 和 ElementTree
xml 是一个树形结构,lxml 使用etree._Element和 etree._ElementTree来分别代表树中的节点和树,etree.ELement和 etree.ElementTree 分别是两个工厂函数
t=root.getroottree()
print t
# <lxml.etree._ElementTree object at 0x7fedd2caca28>
#获得一个结点对应的树对象
print t.getroot()
# <Element root at 0x7fbd2ecb3a70>
#返回树的根结点
foo_tree=etree.ElementTree(root[0])
#从foo这个节点构造一个树,那么这个节点就是这个树的根
print foo_tree
# <lxml.etree._ElementTree object at 0x7f1bf391e998>
print foo_tree.getroot().tag
# foo
XPath
_Element和 _ElementTree 分别具有xpath 函数,两者的区别在于:
如果是相对路径,_Element.xpath是以当前节点为参考的,_ElementTree.xpath以根为参考
如果是绝对路径,_ElementTree.xpath是以当前节点的getroottree的根节点为参考的
foo=root[0]
print foo.xpath('/root')[0].tag
# root
print foo.xpath('.')[0].tag
# foo
t=root.getroottree()
print t.xpath('/root')[0].tag
# root
print t.xpath('.')[0].tag
# root