zoukankan      html  css  js  c++  java
  • Python爬虫解析htm时lxml的HtmlElement对象获取和设置inner html方法

    Python的lxml是一个相当强悍的解析html、XML的模块,最新版本支持的python版本从2.6到3.6,是写爬虫的必备利器。它基于C语言库libxml2 和 libxslt,进行了Python范儿(Pythonic)的绑定,成为一个具有丰富特性又容易使用的Python模块。虽然特性丰富,但是它在修改数节点时又缺少了些接口,比如本文讲到的获取 inner html 和 设置(修改)inner html功能。

    解析网页的html一般使用lxml.html模块,步骤很简单分三步走:

    (1) 导入模块:

    import lxml.html

    (2) 把html转换为html document 树,根节点就是<html>标签:

    doc = lxml.html.fromstring(html)

    (3) 使用xpath查找要提取的节点:

    nodes = doc.xpath('//div[@class, 'the']/div[@id, 'xpath']')

    以上三步分成简洁,实际使用中,可能要反复第三部,通过不同的xpath获得不同的节点进行数据提取。

    可以说,lxml解析(只读模式)html的功能又强大又方便。但是,如果需要修改(写模式)某些节点的html就有点困难了,它在这方面提供的API很少,只有修改节点tag属性的API,比如修改节点的class,id,href等属性是可以的。

    那么如何操作节点的实际html字符串呢?

    1. 获取节点的inner html
    那么,什么是inner html呢?首先,我们来看一段html代码示例:

    <div class=”text”>这是div<a href=”/node”>节点</a>内容</div>

    对于div 这个html标签节点,它的inner html就是:

    这是div<a href=”/node”>节点</a>内容

    即该标签包含的所有内容;而包含div标签在内的全部示例代码就是div的outer html。

    明白了inner html 和 outer html的概念,我们就着手获取它们。

    lxml.html.tostring(html_element) 接口的作用是把一个节点及其子节点形成的树转换成html,也就是该节点的outer html,由此我们来获得inner html,并实现为以下函数:

    def get_inner_html(node):                                                                                                                                                  
        html = lxml.html.tostring(node, encoding="utf8").decode('utf8')            
        p_begin = html.find('>') + 1                                               
        p_end = html.rfind('<')                                                    
        return html[p_begin: p_end]
    

     

    2. 设置节点的inner html
    设置inner html相较于获取更复杂一些,我们还是以上面那段html代码为例:

    <div class=”text”>这是div<a href=”/node”>节点</a>内容</div>

    假设我们要把它的inner html 改成如下字符串:

    this is div<a href=”/node”>node</a>text

    则操作步骤是:

    清空节点div里面的内容:包括它的text和子节点

    把新的inner html转变成fragments

    把fragments加到清空后的div节点

    把以上步骤写出Python函数就是:

    def set_inner_html(node, html):
        node.text = ''
        for child in node.getchildren():
            node.remove(child)                                                                                                                                           4     
        fragments = lxml.html.fragments_fromstring(html)
        if type(fragments[0]) == str:
            node.text = fragments.pop(0)
        node.extend(fragments)
    

      

    通过以上函数就可以成功把node里面的内容设置成想要的html内容,适合在动态修改网页结构内容时使用。

    更多Python技术文章可以看 猿人学 

    除了博客园,我还自己开了一个博客猿人学Python写Python教程和Python爬虫教程
  • 相关阅读:
    文件的增删改查
    集合的使用
    字典的使用
    字符串常用操作
    简单购物车程序练习题
    列表
    数据运算数据类型与
    模块初识
    数据库时间设置
    ubuntu 修改时区
  • 原文地址:https://www.cnblogs.com/amiza/p/10153052.html
Copyright © 2011-2022 走看看