lxml接口说明

lxml 是一个功能强大且高效的 Python 库,用于处理 XML 和 HTML 文档。它基于 C 库 libxml2libxslt,提供了高性能的解析、查询和转换功能,广泛用于网页抓取、XML 数据处理和文档操作。lxml 的主要接口包括 lxml.etree(XML 处理和 ElementTree API)、lxml.html(HTML 解析和清理)以及其他辅助模块。以下是对 lxml 主要接口的详细说明,包括核心类、方法、属性和常见用法,辅以简要示例,旨在帮助开发者快速理解和使用 lxml。


一、lxml 的主要模块

  1. lxml.etree
  • 核心模块,用于解析、操作 XML 和 HTML 文档。
  • 提供 ElementTree API,支持树状结构操作和 XPath 查询。
  • 适合处理严格的 XML 和简单的 HTML。
  1. lxml.html
  • 专门用于解析和处理 HTML 文档,优化了不规范 HTML 的处理。
  • 提供 HTML 清理、表单处理和 CSS 选择器支持。
  1. 其他模块
  • lxml.cssselect:支持 CSS 选择器,转换为 XPath 查询。
  • lxml.objectify:将 XML 转换为 Python 对象,简化数据访问。
  • lxml.sax:支持 SAX 风格的 XML 解析。
  • lxml.builder:用于快速构建 XML 树。

二、lxml.etree 接口详解

lxml.etree 是 lxml 的核心模块,提供 XML 和 HTML 解析、XPath 查询和 DOM 操作功能。以下是主要类和方法的说明。

1. 核心类

  • etree.Element
  • 表示 XML/HTML 文档中的一个节点(标签)。
  • 属性:
    • tag:节点标签名(字符串,如 'book')。
    • text:节点的文本内容(字符串,如 'Apple')。
    • tail:节点后的尾随文本(标签闭合后的文本)。
    • attrib:字典,包含节点的属性(如 {'class': 'company'})。
  • 方法:
    • get(key, default=None):获取属性值,如 element.get('href')
    • set(key, value):设置属性值,如 element.set('class', 'new')
    • append(child):添加子节点。
    • find(path):查找第一个匹配的子节点(支持简单路径或 XPath)。
    • findall(path):查找所有匹配的子节点。
    • xpath(expression):执行 XPath 查询,返回节点或值列表。
    • iter(tag=None):迭代所有子节点(或指定标签)。
    • remove(child):移除子节点。
  • etree.ElementTree
  • 表示整个 XML/HTML 文档树。
  • 属性:
    • docinfo:文档信息(如 XML 声明、编码)。
    • getroot():获取文档根节点(Element 对象)。
  • 方法:
    • xpath(expression):对整个文档执行 XPath 查询。
    • write(file, encoding='utf-8', pretty_print=True):将文档写入文件。
  • etree.XMLParser
  • 解析器配置,用于控制解析行为。
  • 参数:
    • remove_blank_text:移除空白文本节点(适合 XSLT)。
    • recover:尝试恢复不规范的 XML/HTML。
    • encoding:指定输入编码。

2. 解析函数

  • etree.fromstring(text, parser=None)
  • 从字符串解析 XML/HTML,返回 Element 对象(文档根节点)。
  • 示例: from lxml import etree xml = '<root><child>Test</child></root>' element = etree.fromstring(xml) print(element.tag) # 输出: root
  • etree.parse(source, parser=None)
  • 从文件或文件对象解析 XML/HTML,返回 ElementTree 对象。
  • 示例: tree = etree.parse('input.xml') root = tree.getroot()
  • etree.tostring(element, encoding='utf-8', pretty_print=False)
  • 将节点或树序列化为字符串。
  • 参数:
    • encoding:输出编码(如 'utf-8''unicode')。
    • pretty_print:格式化输出(添加换行和缩进)。
  • 示例:
    python print(etree.tostring(root, pretty_print=True).decode())

3. XPath 支持

  • element.xpath(expression, namespaces=None)
  • 执行 XPath 查询,返回节点、属性或文本列表。
  • 参数:
    • expression:XPath 表达式(如 '//book/title/text()')。
    • namespaces:命名空间映射字典。
  • 示例: titles = root.xpath('//book/title/text()') print(titles) # 输出: ['Everyday Italian', 'Harry Potter', ...]
  • 常见 XPath 表达式
  • //tag:查找所有指定标签。
  • @attr:提取属性值(如 //book/@category)。
  • text():提取文本内容。
  • [condition]:条件过滤(如 //book[@category="web"])。
  • ./:相对路径(如 ./title/text())。

4. XSLT 支持

  • etree.XSLT(xslt_element)
  • 创建 XSLT 转换器,用于将 XML 转换为其他格式。
  • 示例:
    python xslt = etree.fromstring('<xsl:stylesheet version="1.0" ...>...</xsl:stylesheet>') transform = etree.XSLT(xslt) result = transform(root)

5. 其他功能

  • 命名空间处理
  • 使用 namespaces 参数处理 XML 命名空间: namespaces = {'ns': 'http://example.com'} nodes = root.xpath('//ns:tag', namespaces=namespaces)
  • 迭代解析
  • 使用 etree.iterparse() 逐块解析大型 XML 文件,节省内存:
    python for event, elem in etree.iterparse('large.xml', tag='book'): print(elem.xpath('./title/text()')[0]) elem.clear() # 释放内存

三、lxml.html 接口详解

lxml.html 是专门为 HTML 解析和处理设计的模块,优化了不规范 HTML 的处理,适合网页抓取。

1. 核心类和函数

  • lxml.html.fromstring(html)
  • 从字符串解析 HTML,返回 Element 对象。
  • 自动处理不规范 HTML(如缺失闭合标签)。
  • 示例: from lxml import html doc = html.fromstring('<div>Hello</div>') print(doc.text) # 输出: Hello
  • lxml.html.parse(source)
  • 从文件或 URL 解析 HTML,返回 ElementTree 对象。
  • lxml.html.clean_html(element)
  • 清理 HTML,移除脚本、样式等不安全内容。
  • 示例: dirty_html = '<div><script>alert("x")</script>Hello</div>' cleaned = html.clean_html(html.fromstring(dirty_html)) print(html.tostring(cleaned).decode()) # 输出: <div>Hello</div>
  • lxml.html.HtmlElement
  • 继承 etree.Element,添加 HTML 特定方法:
    • cssselect(expr):使用 CSS 选择器查询(如 div.company)。
    • forms:获取 HTML 表单。
    • drop_tag():移除标签但保留内容。

2. CSS 选择器

  • 使用 cssselect 模块将 CSS 选择器转换为 XPath:
  from lxml.html import fromstring
  doc = fromstring('<div class="company">Apple</div>')
  elements = doc.cssselect('div.company')
  print(elements[0].text)  # 输出: Apple

3. 表单处理

  • 解析和操作 HTML 表单:
  form = doc.xpath('//form')[0]
  print(form.form_values())  # 获取表单字段和值

四、结合示例解析接口

以下使用提供的 XML 内容展示 lxml.etreelxml.html 的主要接口:

from lxml import etree

content = """<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>
<book category="web">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>
</bookstore>
"""

# 解析 XML
tree = etree.fromstring(content.strip())
root = tree  # 根节点 <bookstore>

# 1. 使用 Element 属性和方法
print("=== 遍历子节点 ===")
for book in root:  # 迭代 <book> 子节点
    print(f"Tag: {book.tag}, Category: {book.get('category')}")

# 2. 使用 XPath 查询
print("\n=== XPath 查询标题 ===")
titles = root.xpath('//book/title/text()')
print(titles)  # 输出: ['Everyday Italian', 'Learning XML']

# 3. 修改 XML
print("\n=== 修改价格 ===")
for book in root.xpath('//book'):
    price = float(book.xpath('./price/text()')[0])
    book.xpath('./price')[0].text = str(price * 1.1)  # 增加 10%
print(etree.tostring(root, pretty_print=True).decode())

# 4. 使用 lxml.html(假设 XML 作为 HTML 处理)
from lxml import html
doc = html.fromstring(content.strip())
print("\n=== 使用 CSS 选择器 ===")
titles = doc.cssselect('book > title')
for title in titles:
    print(title.text)

输出

=== 遍历子节点 ===
Tag: book, Category: cooking
Tag: book, Category: web

=== XPath 查询标题 ===
['Everyday Italian', 'Learning XML']

=== 修改价格 ===
<bookstore>
<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>33.0</price>
</book>
<book category="web">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>43.945</price>
</book>
</bookstore>

=== 使用 CSS 选择器 ===
Everyday Italian
Learning XML

五、注意事项

  1. 安装依赖
  • 确保安装 libxml2libxslt(Linux: sudo apt-get install libxml2-dev libxslt1-dev)。
  • 安装 lxml:pip install lxml.
  1. 错误处理
  • 处理 XML 解析错误:
    python try: tree = etree.fromstring(content) except etree.XMLSyntaxError as e: print(f"Parse error: {e}")
  1. XPath 学习
  • 熟悉 XPath 语法(如 //, @, text())是关键。
  • 使用工具(如 Chrome 开发者工具)生成 XPath。
  1. 性能优化
  • 使用 lxml.etreelxml.html 更快,适合严格 XML。
  • 对于大型文件,使用 iterparse() 节省内存。
  1. 合法性
  • 抓取网页时遵守服务条款和 robots.txt

六、文档和资源

  • 官方文档:https://lxml.de/
  • API 参考:https://lxml.de/api/index.html
  • PyPI:https://pypi.org/project/lxml/
  • GitHub:https://github.com/lxml/lxml
  • XPath 教程:https://www.w3schools.com/xml/xpath_intro.asp

七、总结

lxml 提供强大的 lxml.etreelxml.html 接口,适合处理 XML 和 HTML 文档。etree 提供 ElementTree 和 XPath 操作,适合精确查询和修改;lxml.html 优化了 HTML 解析和清理,适合网页抓取。相比 Beautiful Soup,lxml 更快但 API 更底层;相比 Bluemoss,lxml 更灵活但需要手动组织数据。如果您需要特定接口的深入示例(如 XSLT、表单处理)或处理特定 XML/HTML,请告诉我!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注