当前位置: 首页>大数据>正文

爬虫12:解析器lxml

python中,主要使用 lxml 库来进行xpath获取(在框架中不使用lxml,框架内直接使用xpath即可)
lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据。
lxml和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器,快速的定位特定元素以及节点信息。

1. 安装

pip install lxml

2. lxml使用流程

  • 导入模块
    from lxml import etree
    注:pycharm中etree下方会有红色波浪线但不影响
  • 创建HTML解析对象
    parse_html = etree.Element(html) # 读取文本,自动转换为符合规范的HTML文档格式
    注:返回类型:<class 'lxml.etree._Element'>,返回值<Element html at 0x1448fcc3dc0>
  • 调用xpath表达式
    r_list = parse_html.xpath("Xpath表达式") # list类型
# 标签元素转为字符串
# res = etree.tostring(parse_html)  # 字节类型
# print(type(res))  # <class 'bytes'>
# print(res.decode("utf-8"))

3. lxml库数据提取

3.1 etree.parse 读取HTML文件进行解析

html = etree.parse("baidu_百草.html", etree.HTMLParser())
# parse(self, source, parser=None)
# Load external XML document into element tree.
#         *source* is a file name or file object, 文件或文件对象
#         *parser* is an optional parser instance that defaults to XMLParser.
#         解析器,默认XMLParser;若指定HTMLParser会修复HTML文件中缺失内容,如声明
#         ParseError is raised if the parser fails to parse the document.
#         Returns the root element of the given source document.
#         返回<lxml.etree._ElementTree object at 0x00000237143BD3C0>,类型<class 'lxml.etree._ElementTree'>
res = etree.tostring(html)  # 解析成字节类型

3.2 html.xpath 获取节点

from lxml import etree

with open("baidu_百草.html", "r", encoding="utf-8") as f:
    html = f.read()
# 2. 创建HTML解析对象(读取文本)
parse_html = etree.HTML(html)  
# 3. 调用xpath表达式
xpath = "//h3//a[@tabindex]//text()"  # 获取a的文本
xpath = "//h3//a[@tabindex]/@href"  # 获取a的href属性值
xpath = "//*"  # 获取所有节点
xpath = "//a[@href="link2.html"]/parent::*/@class"  # 父级元素匹配
xpath = "//a[@href="link2.html"]/../@class"  # 父级元素匹配..
xpath = "//li[contains(@class,"aaa") and @name="fore"]/a/text()"  # 多属性匹配and
r_list = parse_html.xpath(xpath)
print(r_list)
# 输出1:['青岛', '百草', '新材料股份有限公司', '百草', '乳膏 - 京东', ……]
# 输出2:['http://www.baidu.com/link?url=xx', 'http://www.baidu.com/link?url=xx',……]
# 输出3:[<Element html at 0x1a7f12be540>, ……]
# body = etree.Element("body")
# tree.append(body)  # 添加body为子级
# sub = etree.SubElement(body, "p")  # 添加子节点
# sub = etree.SubElement(body, "div").append(etree.Element("child"))

4. 示例

# 目标:获取所有h3的文本
xpath = "//h3//a[@tabindex]/text()"  # 获取a的所有文本
# 但是下图中a的文本通过em标签分割,若全量获取,则无法区分
xpath = "//h3/a[@tabindex]" # 获取a元素
r_list = parse_html.xpath(xpath) 
print(r_list)
for ele in r_list:
    res = "".join(ele.xpath(".//text()"))   
# ele.xpath 再次提取数据;拼接后获取需要的值
# . 表示当前节点
爬虫12:解析器lxml,第1张
示例图
  • 核对后发现有遗漏的h3:该h3子元素a无tabindex属性


    爬虫12:解析器lxml,第2张
    遗漏的h3
  • 修改xpath:xpath = "//h3";核对后发现输出多余结果
    爬虫12:解析器lxml,第3张
  • 修改xpath:xpath = "//h3/a[1]" ,满足要求

参考

  1. python3解析lxml
  2. python lxml库的安装和使用
  3. python lxml解析库实战

https://www.xamrdz.com/bigdata/7gq1897092.html

相关文章: