美文网首页
爬虫12:解析器lxml

爬虫12:解析器lxml

作者: _百草_ | 来源:发表于2022-07-29 18:13 被阅读0次

    在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 再次提取数据;拼接后获取需要的值
    # . 表示当前节点
    
    示例图
    • 核对后发现有遗漏的h3:该h3子元素a无tabindex属性


      遗漏的h3
    • 修改xpath:xpath = "//h3";核对后发现输出多余结果
      image.png
    • 修改xpath:xpath = "//h3/a[1]" ,满足要求

    参考

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

    相关文章

      网友评论

          本文标题:爬虫12:解析器lxml

          本文链接:https://www.haomeiwen.com/subject/olixirtx.html