最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Python之XML、HTML和Xpath相关介绍

    正文概述    2020-09-24   159

    Python之XML、HTML和Xpath相关介绍

    当我们处理HTML文档感到十分棘手的时候,我们可以先将HTML文件转换成XML文档,然后用XPath查找HTML节点或元素。

    什么是XML

    (1)XML 是可扩展标记语言(EXtensible Markup Language)

    (2)XML 是一种标记语言,很类似 HTML

    (3)XML 的设计宗旨是传输数据,而非显示数据

    (4)XML 的标签需要我们自行定义。

    (5)XML 被设计为具有自我描述性。

    (6)XML 是 W3C 的推荐标准。

    XML 和 HTML 的区别

    Python之XML、HTML和Xpath相关介绍XML文档示例

    <?xml version="1.0" encoding="utf-8"?>
    <bookstore>
      <book category="cooking">
        <title>this is title</title>
        <content>hello world</>
      </book>
    </bookstore>

    HTML DOM 模型示例

    HTML DOM 定义了访问和操作 HTML 文档的标准方法,以树结构方式表达 HTML 文档。

    Python之XML、HTML和Xpath相关介绍

    什么是XPath?

    XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。

    XPath 开发工具

    (1)开源的XPath表达式编辑工具:XMLQuire(XML格式文件可用)

    (2)Chrome插件 XPath Helper

    (3)Firefox插件 XPath Checker

    选取节点

    XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

    下面列出了最常用的路径表达式:

    Python之XML、HTML和Xpath相关介绍

    在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

    Python之XML、HTML和Xpath相关介绍

    谓语(Predicates)

    谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。

    在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

    Python之XML、HTML和Xpath相关介绍选取未知节点

    XPath 通配符可用来选取未知的 XML 元素。

    Python之XML、HTML和Xpath相关介绍

    在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

    Python之XML、HTML和Xpath相关介绍

    选取若干路径

    通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

    在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

    Python之XML、HTML和Xpath相关介绍

    XPath的运算符

    下面列出了可用在 XPath 表达式中的运算符:

    Python之XML、HTML和Xpath相关介绍

    这些就是XPath的语法内容,在运用到Python抓取时要先转换为xml。

    相关推荐:《Python视频教程》

    lxml库

    lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据。

    lxml和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器,我们可以利用之前学习的XPath语法,来快速的定位特定元素以及节点信息。

    lxml python 官方文档:http://lxml.de/index.html

    需要安装C语言库,可使用 pip 安装:pip install lxml (或通过wheel方式安装)

    我们利用它来解析 HTML 代码,简单示例:

    from lxml import etree
    
    text = '''
    <div>
        <ul>
             <li><a href="link1.html">first item</a></li>
             <li><a href="link2.html">second item</a></li>
             <li><a href="link3.html">third item</a></li>
             <li><a href="link4.html">fourth item</a></li>
             <li><a href="link5.html">fifth item</a> # 注意,此处缺少一个 li 闭合标签
         </ul>
     </div>
    '''
    
    # 利用etree.HTML,将字符串解析为HTML文档
    html = etree.HTML(text)
    
    # 按字符串序列化HTML文档
    # html = etree.tostring(html).decode("utf8")  # 不能正常显示中文
    html = etree.tostring(html, encoding="utf-8", pretty_print=True, method="html").decode("utf-8")  # 可以正常显示中文
    
    print(html)

    运行结果如下:

    <html><body>
    <div>
        <ul>
             <li><a href="link1.html">first item</a></li>
             <li><a href="link2.html">second item</a></li>
             <li><a href="link3.html">third item</a></li>
             <li><a href="link4.html">fourth item</a></li>
             <li>
    <a href="link5.html">fifth item</a> # 注意,此处缺少一个 li 闭合标签
         </li>
    </ul>
    </div>
    </body></html>

    lxml 可以自动修正 html 代码,例子里不仅补全了 li 标签,还添加了 body,html 标签。

    文件读取:

    除了直接读取字符串,lxml还支持从文件里读取内容。我们新建一个 index.html 文件:

    <div>
        <ul>
             <li><a href="link1.html">first item</a></li>
             <li><a href="link2.html">second item</a></li>
             <li><a href="link3.html"><span>third item</span></a></li>
             <li><a href="link4.html">fourth item</a></li>
             <li><a href="link5.html">fifth item</a></li>
         </ul>
     </div>

    再利用 etree.parse() 方法来读取文件。

    from lxml import etree
    
    # 读取外部文件 hello.html
    html = etree.parse('./index.html', etree.HTMLParser())  # 指定解析器HTMLParser会根据文件修复HTML文件中缺失的如声明信息
    html = etree.tostring(html, encoding="utf-8", pretty_print=True, method="html").decode("utf-8")
    
    print(html)

    运行结果:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html><body><div>
        <ul>
             <li><a href="link1.html">first item</a></li>
             <li><a href="link2.html">second item</a></li>
             <li><a href="link3.html"><span>third item</span></a></li>
             <li><a href="link4.html">fourth item</a></li>
             <li><a href="link5.html">fifth item</a></li>
         </ul>
     </div></body></html>

    接下来我们看一下 XPath 的实力测试。

    1. 获取所有的 <li> 标签

    from lxml import etree
     
    html = etree.parse('./index.html', etree.HTMLParser())
    print(type(html))  # <class 'lxml.etree._ElementTree'>
    
    result = html.xpath('//li')
    
    print(result)  # [<Element li at 0x109c66248>, <Element li at 0x109c66348>, <Element li at 0x109c66388>, 
    <Element li at 0x109c663c8>, <Element li at 0x109c66408>]
    print(len(result))  # 5
    print(type(result))  # <class 'list'>
    print(type(result[0]))  # <class 'lxml.etree._Element'>

    2. 继续获取<li> 标签的所有 class属性

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//li/@class')
    
    print(result)  # ['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']

    3. 继续获取<li>标签下hre 为 link1.html 的 <a> 标签

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//li/a[@href="link1.html"]')
    
    print(result)  # [<Element a at 0x10b324288>]

    4. 获取<li> 标签下的所有 <span> 标签

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    # result = html.xpath('//li/span')
    # 注意这么写是不对的:因为 / 是用来获取子元素的,而 <span> 并不是 <li> 的子元素,所以,要用双斜杠
    
    result = html.xpath('//li//span')
    
    print(result)  # [<Element span at 0x10a59b308>]

    5. 获取 <li> 标签下的<a>标签里的所有 class

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//li/a//@class')
     
    print(result)  # ['bold']

    6. 获取最后一个 <li> 的 <a> 的 href

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//li[last()]/a/@href')
    # 谓语 [last()] 可以找到最后一个元素
     
    print(result)  # ['link5.html']

    7. 获取倒数第二个元素的内容

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//li[last()-1]/a')
    
    # text 方法可以获取元素内容
    print(result[0].text)  # fourth item

    8. 获取 class 值为 bold 的标签名

    from lxml import etree
    
    html = etree.parse('./index.html', etree.HTMLParser())
    result = html.xpath('//*[@class="bold"]')
    
    # tag方法可以获取标签名
    print(result[0].tag)  # span

    起源地下载网 » Python之XML、HTML和Xpath相关介绍

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元