对于lxml的定义,我想官方文档描述的会更为准确一些:
lxml XML 工具包是 C 库 libxml2和libxslt的 Pythonic 绑定。它的独特之处在于它将这些库的速度和XML 功能完整性与原生 Python API 的简单性结合在一起,大部分兼容但优于众所周知的 ElementTree API。最新版本适用于从 2.7 到 3.9 的所有 CPython 版本。
通俗的来讲,lxml对C语言libxml2和libxslt绑定的Pythonic风格的代码
通常情况下它们可以是一个东西,都是标记语言。当你使用lxml的时候,我喜欢众生平等,一视同仁。当然,它们是有区别的,而且区别很大,只不过当使用lxml的时候绝大部分情况是平等的。
lxml从名字不难看出,是处理xml的
生成html文本:
简单解释下,etree.dump(),在源码中我们可以看到,作者提醒我们“ should be used for debugging only.“ 也就是告诉我们这个方法应该只用在调试的时候,在控制台看结果。
pretty_print望文生义,是为了让输出更美观,我不喜欢美观这种说法,准确来说应该是更直观。
from lxml import etree
root = etree.Element("html")
head = etree.SubElement(root, "head")
title = etree.SubElement(head, "title")
title.text = "This is Page Title"
body = etree.SubElement(root, "body")
heading = etree.SubElement(body, "h1", style="font-size:20pt", id="head")
heading.text = "Hello World!"
para = etree.SubElement(body, "p", id="firstPara")
para.text = "This HTML is XML Compliant!"
para = etree.SubElement(body, "p", id="secondPara")
para.text = "This is the second paragraph."
etree.dump(root)
with open("demo.html" ,'wb') as f:
f.write(etree.tostring(root,pretty_print=True))
<html>
<head>
<title>This is Page Titletitle>
head>
<body>
<h1 style="font-size:20pt" id="head">Hello World!h1>
<p id="firstPara">This HTML is XML Compliant!p>
<p id="secondPara">This is the second paragraph.p>
body>
html>
读取文件(xml,html):
parse方法的定义parse(source, parser=None, base_url=None)。源码中对source的说明,可以是任何东西。
The ``source`` can be any of the following:
- a file name/path
- a file object
- a file-like object
- a URL using the HTTP or FTP protocol
from lxml import etree
tree = etree.parse('demo.html')
root = tree.getroot()
etree.dump(root)
作为一个xpath党,我不推荐除xpath以外的任何方式。做前端的人员可以使用css选择器,几乎没有学习成本,但是奈何我从第一次使用xpath后就再也没用过其他方式了。
xpath可以很傻瓜,也可以很智能。如果你觉得xpath不好用,那一定是你不懂语法规则,没错肯定是你的错不是它的错
xpath的语法(可以看python官方库xml中对xpath的语法介绍)
https://docs.python.org/3/library/xml.etree.elementtree.html
例如我们拿到了root,也就是xml最外层的标签对,我们可以称之为元素。
元素有什么特点呢,不妨看源码中_Element类,我当然知道你不会去看,也没必要看。
它有 tag,text,attrib 这几个我们常用的属性,例如:
from lxml import etree
tree = etree.parse('demo.html')
root = tree.getroot()
print(root.tag)
print(root.text)
print(root.attrib)
它还有一些方法:find,findall。我展示了三种获取h1标签中的文本信息“Hello World!”的方式
from lxml import etree
tree = etree.parse('demo.html')
root = tree.getroot()
print(root.find('.//head/title').text)
print(root.find(".//*[@id='head']").text)
print(root.find(".//body/h1[@style]").text)
print(root.find(".//body/h1").text)
print(root.find(".//body/h1").attrib['style'])
展示下findall的使用:
顺便打个广告:xpath的强大远超过你的想象
from lxml import etree
tree = etree.parse('demo.html')
root = tree.getroot()
print(root.findall(".//*p")[0].text)
elements = root.findall(".//*p")
for e in elements:
print(e.text)
之前有一段时间没有使用xpath,发现一些库对于旧的xpath写法有些警告,不过不重要了,反正能跑,不是吗?
一般我们把root作为根节点,从根节点往下找
.//
.指的是当前节点
//指的是所有子元素,
这种方式是非常实用的,我们可以搜寻到任意节点,在该节点上用.//方式搜寻其下面的子元素
* 代表的是所有