精华内容
下载资源
问答
  • 2022-05-15 02:14:27

    今天给大家介绍lxml库的基本使用方法。

    目录

    一、lxml库简介

    二、初始化

    三、xpath(lxml)语法讲解

    四、总结


    一、lxml库简介

            lxml库是python的第三方库,安装方式也是十分简单,这里就不多赘述。而lxml库的特点就是简单和易上手,并且解析大型文档(特指xml或html文档)的速度也是比较快的,因此写爬虫解析网页的时候它也是我们的一个不错的选择。

    二、初始化

    使用lxml库的第一个步骤永远是初始化,只有初始化之后我们才可以去使用它的语法。

    初始化方法如下:

    html = etree.HTML(text)

    1>参数:

    text :html内容的字符串

    2>返回值:

    html :  一个lxml库的对象

    示例:

    from lxml import etree  #我们主要使用的lxml库中的etree库
    text = '''
    <body>
        <div class="key">
            <div class="iocnBox"><i class="iconfont icon-delete"></i></div>
            <div class="empty">清空</div>
            <textarea placeholder="在此述说新年寄语..." rows="1" class="van-field__control"></textarea>
            <div class="buts">发送</div>
        </div>
    '''
    #开始初始化
    html = etree.HTML(text)  #这里需要传入一个html形式的字符串

    三、xpath(lxml)语法讲解

    也许你会惊讶,说我们不是在讲解lxml库吗?为什么这里写的是xpath语法?好吧,其实我忘记说了,lxml库的语法就是基于xpath语法来的,所以会了xpath语法,自然就会了lxml语法,xpath语法在我们这个爬虫系列的第一部分就讲过了,忘了的同学可以去看看。

    而且观察返回的结果,发现大部分返回的都是以列表的形式返回的结果,这一点请注意。

    1>语法1:寻找节点

    语法含义
    nodename(节点名字)直接根据写的节点名字查找节点,如:div
    //在当前节点下的子孙节点中寻找,如://div
    /在当前节点下的子节点中寻找,如:/div
    .代表当前节点(可省略不写,就像我们有时候写的相对路径),如:./div
    ..当前节点的父节点,如:../div

    示例1---子孙节点:

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = html.xpath('//div') #使用xpath语法,一是在子孙节点中寻找,二是寻找div的标签
    print(result)
    #结果:
    #[<Element div at 0x1e4cadbf608>, <Element div at 0x1e4cae512c8>, <Element div at 0x1e4cae51348>]

     首先,说明下lxml如何使用xpath语法:

    使用方法就是对初始化的对象调用xpath(str)方法即可,这里参数为传入的xpath语法字符串。

    其次,分析下上面的代码:

    首先,我们初始化一个html对象,然后调用在此基础上调用xpath语法,其中传入的参数为://div,意思是寻找其中的div标签。然后我们观察text字符串中的html代码,可以看见,里面总共只有三个div标签,符合结果。(div标签是成对出现,一组为:<div></div>)

    示例2---子节点:

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = html.xpath('/html/body/div')
    print(result)
    #结果:
    #[<Element div at 0x1ea38b7f4c8>, <Element div at 0x1ea38c11188>]

    首先,说明下lxml库的一个功能:补全与完善功能。

    即我们传入的html代码不是标准的html代码,因为标准的html代码结构如下。

    #标准结构
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     <!--主题代码 -->
    </body>
    </html>

     虽然我们传入的不是完整结构,但是lxml会在一定程度上完善我们的html代码,尽量使它变为标准的结构。那么如何查看这个事实呢?只需要调用etree.tostring(html)结果。如下:

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = etree.tostring(html)
    print(result)
    #结果如下,中文没有正常显示,但是结构是正确的
    '''
    <html><body>
        <div>&#36825;&#26102;&#27979;&#35797;&#30340;div</div>
        <div>
            <div>
                &#36825;&#26159;&#23884;&#22871;&#30340;div&#26631;&#31614;
                <p>
                    &#36825;&#26102;&#23884;&#22871;&#30340;p&#26631;&#31614;
                </p>
            </div>
        </div>
        <p>&#36825;&#26102;&#27979;&#35797;&#30340;p</p>
    </body>
    </html>
    '''

     其次,分析下代码的结果。我们这里传入的xpath语法为:/html/body/div 。这样我们首先获取了html标签。在获取的了html标签内的body标签,而属于body内的子节点的div总共有两个。故结果打印两个标签。

    2>语法2:筛选

    有时候单纯的选择还不够,因为我们有时候需要的信息只在某一种标签中的某一个标签中,如一个网页中有很多的div标签,但是只有拥有class="hello"的属性的标签才具有我们需要的信息。因此,掌握一些筛选的方法是必须的事情。

    重要说明:

    当我们使用筛选时,筛选的方法都是包含在[](中括号)中的。

    方法集合一:属性筛选

    方法名\符号作用
    @获取属性或者筛选属性,如:@class
    contains判断属性中是否含有某个值(用于多值判断),如:contains(@class,'hello')

            属性筛选示例:

    from lxml import etree
    
    text = '''
    <div class="hello">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    #根据单一属性筛选
    
    #筛选出class="hello"的div标签
    hello_tag = html.xpath('//div[@class="hello"]')  #注意筛选的方法都是在中括号里面的
    print(hello_tag) #结果为: [<Element div at 0x2ba41e6d088>],即找到了一个标签,符合条件
    
    #找出具有name="btn"的input标签
    input_tag = html.xpath('//input[@name="btn"]')
    print(input_tag) #结果为:[<Element input at 0x1751d29df08>],找到一个input标签,符合条件
    
    #筛选出具有class="hello"的div标签
    hello_tags = html.xpath('//div[contains(@class,"hello")]')
    print(hello_tags) #结果为:[<Element div at 0x1348272d248>, <Element div at 0x1348272d6c8>],即找到了两个div标签,符合条件

    方法集合二:按序选择

    有时候我们会有这样的需求,我们爬取的内容是一个table标签(表格标签),或者一个ul(标签),了解过html的应该都知道这样的标签,内部还有很多标签,比如table标签里就有tr、td等,ul里面就有li标签等。对于这样的标签,我们有时候需要选择第一个或者最后一个或者前几个等。这样的方式我们也可以实现。

    方法作用
    last()获取最后一个标签
    1获取第一个标签
    position() < = > num筛选多个标签(具体见实例)

            按序选择示例:

    这里需要注意这里的序是从1开始而不是从0开始

    from lxml import etree
    
    text = '''
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ul>     
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个li标签
    first_tag = html.xpath('//li[1]') #令人吃惊,lxml并没有first()方法
    print(first_tag)
    
    #获取最后一个li标签
    last_tag = html.xpath('//li[last()]')
    print(last_tag)
    
    #获取前五个标签
    li_tags = html.xpath('//li[position() < 6]')
    print(li_tags)

    方法集合三:逻辑和计算

    其实在写筛选时是可以加入逻辑方法的,如:and、or、>、>=等。当然也是可以写入一些计算方法的,如:+、-等。

    下面给出示例:

    from lxml import etree
    
    text = '''
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ul>     
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第二个li标签,使用=判断
    second_tag = html.xpath('//li[position() = 2]')
    print(second_tag)
    
    #获取第一个和第二个标签,使用or
    tags = html.xpath('//li[position() = 1 or position() = 2]')
    print(tags)
    
    #获取前三个标签,使用<
    three_tags = html.xpath('//li[position()<4]')
    print(three_tags)

    其余的方法使用思路都是一样的。会了一个其余的按照思路写即可。

    3>语法3:获取属性和文本

    好的,终于到这一步了(写得太累了,^_^)。我们寻找标签、筛选标签的最终目的就是获取它的属性或者文本内容。下面讲解获取文本和属性的方法。

    方法作用
    @获取属性或者筛选属性
    text()获取文本

            获取文本示例:

    from lxml import etree
    
    text = '''
    <div class="hello">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个div中的p标签中的文本
    content = html.xpath('//div/p/text()')    #注意使用text()的时机和位置
    print(content)  #结果为:['Hello,this is used to tested'],仍然是以列表形式返回结果
    
    #获取拥有第二个div中的文本,注意观察下面的不同之处
    content_two = html.xpath('//div[position() = 2]/text()')
    print(content_two)  #结果为: ['\n    ', '\n']
    
    content_three = html.xpath('//div[position() = 2]//text()')
    print(content_three)  #结果为: ['\n    ', '\n        ', '你好,这是用于测试的html代码', '\n    ', '\n']
    #两者不同之处在于:一个为//,一个为/。我们知道//获取其子孙节点中的内容,而/只获取其子节点的内容。

      获取属性示例:

    from lxml import etree
    
    text = '''
    <div class="hello" name="test">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个div的name属性
    first_div_class = html.xpath('//div[@class="hello"]/@name')
    print(first_div_class)  #结果为:['test']
    
    #获取input标签的name值
    input_tag_class = html.xpath('//input/@name')
    print(input_tag_class) #结果为:['btn']

    四、总结

            lxml库的讲解差不多就到此为止了,至于更多的方法还是推荐查官方文档。因为有些方法确实不常用。希望看完本篇文章,你能够慢慢掌握xpath语法的使用,并且使用lxml库解析html代码。谢谢大家!

    更多相关内容
  • lxmlpython的一个解析,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它...

    简单介绍一下lxml的用法

    lxml是python的一个解析库,支持HTML和XML格式的解析,XPath,全称XML Path Language,即XML路径语言,很明显是通过路径来定位,通俗点你可以想象成一个树状结构,会有很多节点分支,然后你再回过来看对应的HTML,如果还没看到过可以用谷歌浏览器打开任意网站,右键检查元素,如图所示:
    在这里插入图片描述在这里插入图片描述
    当然我现在只是初步接触lxml,以后如果深入了解后会回来改写这边low气爆爆的文档
    下面代码,上面有相关注释:

    # coding=utf-8
    # coding=utf-8
    import requests
    import json
    import re
    import os
    from lxml import etree
    
    #定义爬取内容方法
    def spider_parse_detail(dxy_url):
        ret=requests.get(dxy_url,headers=headers)
        #判断状态码
        if ret.status_code==200:
            #将数据转化为字典
            dxy_response=ret.content.decode()
            # print(dxy_response)
            html = etree.HTML(dxy_response)
            #定位思路,首先找到回复帖子的大容器,也就是div的最外层,然后发现在大容器下,每一个小容器装这每一位用户的回复内容,所以可以在之前定位的大容器下面进行
            #嵌套定位,然后发现每一个td标签为用户回复的文本内容,所以在笑容其后面跟上对应的td路径就可以获取所有文本了
            back_content_element = html.xpath('//*[@id="postcontainer"]')[0].xpath('div//td[@class="postbody"]')
            #增加一个需求,显示用户名
            user=html.xpath('//*[@id="postcontainer"]')[0].xpath('//div[@class="auth"]/a/text()')
            for user_info,item in zip(user,back_content_element):
                print(user_info,'\n',''.join(item.xpath('text()')).strip())
        else:
            print('状态码为:{}'.format(ret.status_code))
    
    
    if __name__=="__main__":
        url = 'http://www.dxy.cn/bbs/thread/626626#626626'
        headers = {
    
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        }
        spider_parse_detail(url)
    
    
    
    展开全文
  • python爬虫教程:lxml库

    2021-02-08 12:37:11
    python爬虫教程:lxml库 一、前言: ​ hello,大家好,我是小白菜。今天为大家带来的是爬虫教程的第二部分lxml库的讲解。我还记得我最初学习爬虫的时候,只知道一个bs4库,除此之外什么都不知道。后来接触到了lxml...

    python爬虫教程:lxml库

    一、前言:

    ​ hello,大家好,我是小白菜。今天为大家带来的是爬虫教程的第二部分lxml库的讲解。我还记得我最初学习爬虫的时候,只知道一个bs4库,除此之外什么都不知道。后来接触到了lxml库,才发现这个库真的还挺好用的。好的,下面开始为大家讲解一下lxml库的基本使用。

    二、lxml库的基本使用:

    1.lxml库简介:

    ​ lxml库是python的第三方库,安装方式也是十分简单,这里就不多赘述。而lxml库的特点就是简单和易上手,并且解析大型文档(特指xml或html文档)的速度也是比较快的,因此写爬虫解析网页的时候它也是我们的一个不错的选择。

    2.初始化:

    ​ 使用lxml库的第一个步骤永远是初始化,只有初始化之后我们才可以去使用它的语法。

    ​ 初始化方法如下:

    ​ html = etree.HTML(text)

    1>参数:

    text : html内容的字符串

    2>返回值:

    html : 一个lxml库的对象

    示例:

    from lxml import etree		#我们主要使用的lxml库中的etree库
    text = '''
    <body>
        <div class="key">
            <div class="iocnBox"><i class="iconfont icon-delete"></i></div>
            <div class="empty">清空</div>
            <textarea placeholder="在此述说新年寄语..." rows="1" class="van-field__control"></textarea>
            <div class="buts">发送</div>
        </div>
    '''
    #开始初始化
    html = etree.HTML(text)		#这里需要传入一个html形式的字符串
    

    3.xpath(lxml)语法讲解:

    ​ 也许你会惊讶,说我们不是在讲解lxml库吗?为什么这里写的是xpath语法?好吧,其实我忘记说了,lxml库的语法就是基于xpath语法来的,所以会了xpath语法,自然就会了lxml语法。

    ​ 而且观察返回的结果,发现大部分返回的都是以列表的形式返回的结果,这一点请注意。

    1>语法1:寻找节点
    语法含义
    nodename(节点名字)直接根据写的节点名字查找节点,如:div
    //在当前节点下的子孙节点中寻找,如://div
    /在当前节点下的子节点中寻找,如:/div
    .代表当前节点(可省略不写,就像我们有时候写的相对路径),如:./div
    当前节点的父节点,如:…/div

    示例1—子孙节点:

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = html.xpath('//div')	#使用xpath语法,一是在子孙节点中寻找,二是寻找div的标签
    print(result)
    #结果:
    #[<Element div at 0x1e4cadbf608>, <Element div at 0x1e4cae512c8>, <Element div at 0x1e4cae51348>]
    

    首先,说明下lxml如何使用xpath语法:

    ​ 使用方法就是对初始化的对象调用xpath(str)方法即可,这里参数为传入的xpath语法字符串。

    其次,分析下上面的代码:

    ​ 首先,我们初始化一个html对象,然后调用在此基础上调用xpath语法,其中传入的参数为: //div,意思是寻找其中的div标签。然后我们观察text字符串中的html代码,可以看见,里面总共只有三个div标签,符合结果。(div标签是成对出现,一组为:

    示例2—子节点:

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = html.xpath('/html/body/div')
    print(result)
    #结果:
    #[<Element div at 0x1ea38b7f4c8>, <Element div at 0x1ea38c11188>]
    

    首先,说明下lxml库的一个功能:补全与完善功能。

    ​ 即我们传入的html代码不是标准的html代码,因为标准的html代码结构如下。

    #标准结构
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    	<!--主题代码 -->
    </body>
    </html>
    

    ​ 虽然我们传入的不是完整结构,但是lxml会在一定程度上完善我们的html代码,尽量使它变为标准的结构。那么如何查看这个事实呢?只需要调用etree.tostring(html)结果。如下

    from lxml import etree
    
    text = '''
    <body>
        <div>这时测试的div</div>
        <div>
            <div>
                这是嵌套的div标签
                <p>
                    这时嵌套的p标签
                </p>
            </div>
        </div>
        <p>这时测试的p</p>
    </body>
    '''
    
    html = etree.HTML(text)
    result = etree.tostring(html)
    print(result)
    #结果如下,中文没有正常显示,但是结构是正确的
    '''
    <html><body>
        <div>&#36825;&#26102;&#27979;&#35797;&#30340;div</div>
        <div>
            <div>
                &#36825;&#26159;&#23884;&#22871;&#30340;div&#26631;&#31614;
                <p>
                    &#36825;&#26102;&#23884;&#22871;&#30340;p&#26631;&#31614;
                </p>
            </div>
        </div>
        <p>&#36825;&#26102;&#27979;&#35797;&#30340;p</p>
    </body>
    </html>
    '''
    

    其次,分析下代码的结果。我们这里传入的xpath语法为: /html/body/div 。这样我们首先获取了html标签。在获取的了html标签内的body标签,而属于body内的子节点的div总共有两个。故结果打印两个标签。

    2>语法2:筛选

    ​ 有时候单纯的选择还不够,因为我们有时候需要的信息只在某一种标签中的某一个标签中,如一个网页中有很多的div标签,但是只有拥有class="hello"的属性的标签才具有我们需要的信息。因此,掌握一些筛选的方法是必须的事情。

    重要说明:

    ​ 当我们使用筛选时,筛选的方法都是包含在[](中括号)中的。

    方法集合一:属性筛选

    方法名\符号作用
    @获取属性或者筛选属性,如:@class
    contains判断属性中是否含有某个值(用于多值判断),如:contains(@class,‘hello’)

    ​ 属性筛选示例:

    from lxml import etree
    
    text = '''
    <div class="hello">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    #根据单一属性筛选
    
    #筛选出class="hello"的div标签
    hello_tag = html.xpath('//div[@class="hello"]')		#注意筛选的方法都是在中括号里面的
    print(hello_tag)	#结果为: [<Element div at 0x2ba41e6d088>],即找到了一个标签,符合条件
    
    #找出具有name="btn"的input标签
    input_tag = html.xpath('//input[@name="btn"]')
    print(input_tag)	#结果为:[<Element input at 0x1751d29df08>],找到一个input标签,符合条件
    
    #筛选出具有class="hello"的div标签
    hello_tags = html.xpath('//div[contains(@class,"hello")]')
    print(hello_tags)	#结果为:[<Element div at 0x1348272d248>, <Element div at 0x1348272d6c8>],即找到了两个div标签,符合条件
    

    方法集合二:按序选择

    ​ 有时候我们会有这样的需求,我们爬取的内容是一个table标签(表格标签),或者一个ul(标签),了解过html的应该都知道这样的标签,内部还有很多标签,比如table标签里就有tr、td等,ul里面就有li标签等。对于这样的标签,我们有时候需要选择第一个或者最后一个或者前几个等。这样的方式我们也可以实现。

    方法作用
    last()获取最后一个标签
    1获取第一个标签
    position() < = > num筛选多个标签(具体见实例)

    ​ 按序选择示例:

    这里需要注意这里的序是从1开始而不是从0开始

    from lxml import etree
    
    text = '''
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ul>     
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个li标签
    first_tag = html.xpath('//li[1]')	#令人吃惊,lxml并没有first()方法
    print(first_tag)
    
    #获取最后一个li标签
    last_tag = html.xpath('//li[last()]')
    print(last_tag)
    
    #获取前五个标签
    li_tags = html.xpath('//li[position() < 6]')
    print(li_tags)
    

    方法集合三:逻辑和计算

    ​ 其实在写筛选时是可以加入逻辑方法的,如:and、or、>、>=等。当然也是可以写入一些计算方法的,如:+、-等。

    ​ 下面给出示例:

    from lxml import etree
    
    text = '''
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ul>     
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第二个li标签,使用=判断
    second_tag = html.xpath('//li[position() = 2]')
    print(second_tag)
    
    #获取第一个和第二个标签,使用or
    tags = html.xpath('//li[position() = 1 or position() = 2]')
    print(tags)
    
    #获取前三个标签,使用<
    three_tags = html.xpath('//li[position()<4]')
    print(three_tags)
    

    ​ 其余的方法使用思路都是一样的。会了一个其余的按照思路写即可。

    3>语法3:获取属性和文本

    ​ 好的,终于到这一步了(写得太累了,_)。我们寻找标签、筛选标签的最终目的就是获取它的属性或者文本内容。下面讲解获取文本和属性的方法。

    方法作用
    @获取属性或者筛选属性
    text()获取文本

    ​ 获取文本示例:

    from lxml import etree
    
    text = '''
    <div class="hello">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个div中的p标签中的文本
    content = html.xpath('//div/p/text()')    #注意使用text()的时机和位置
    print(content)  #结果为:['Hello,this is used to tested'],仍然是以列表形式返回结果
    
    #获取拥有第二个div中的文本,注意观察下面的不同之处
    content_two = html.xpath('//div[position() = 2]/text()')
    print(content_two)  #结果为: ['\n    ', '\n']
    
    content_three = html.xpath('//div[position() = 2]//text()')
    print(content_three)  #结果为: ['\n    ', '\n        ', '你好,这是用于测试的html代码', '\n    ', '\n']
    #两者不同之处在于:一个为//,一个为/。我们知道//获取其子孙节点中的内容,而/只获取其子节点的内容。
    

    ​ 获取属性示例:

    from lxml import etree
    
    text = '''
    <div class="hello" name="test">
        <p>Hello,this is used to tested</p>
    </div>
    <div class="hello test hi">
        <div>
            <div>你好,这是用于测试的html代码</div>
        </div>
    </div>
    
    <div class="button">
        <div class="menu">
            <input name="btn" type="button" value="按钮" />
        <div>
    </div>
    '''
    
    #初始化
    html = etree.HTML(text)
    
    #获取第一个div的name属性
    first_div_class = html.xpath('//div[@class="hello"]/@name')
    print(first_div_class)  #结果为:['test']
    
    #获取input标签的name值
    input_tag_class = html.xpath('//input/@name')
    print(input_tag_class) #结果为:['btn']
    

    三、总结:

    ​ 好的,lxml库的讲解差不多就到此为止了,至于更多的方法还是推荐查官方文档。因为有些方法确实不常用。谢谢大家!

    展开全文
  • 主要介绍了Python爬虫基于lxml解决数据编码乱码问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Python爬虫lxml模块

    千次阅读 2020-05-09 16:49:34
    Python爬虫lxml模块一:lxml模块简介二:xpath常用规则2.1:读取文件解析节点2.2 读取HTML文件进行解析2.3 获取所有节点2.4 获取子节点2.5 获取父节点2.6 属性匹配2.7 文本获取2.8 属性获取2.9 属性多值匹配2.10 ...

    一:lxml模块简介

    lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
    XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索
    XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择
    XPath于1999年11月16日成为W3C标准,它被设计为供XSLT、XPointer以及其他XML解析软件使用

    二:xpath常用规则

    安装lxml模块:

    pip install lxml
    
    表达式描述
    nodename选取此节点的所有子节点
    /从当前节点选取直接子节点
    //从当前节点选取子孙节点
    .选择当前节点
    选取当前节点的父节点
    @选取属性
    *通配符,选择所有元素节点与元素名
    @*选取所有属性
    [@attrib=‘value’]选取给定属性具有的给定值的所有元素
    [@attrib]选取具有给定属性的所有元素
    [tag]选取所有具有指定元素的直接子节点
    [tag=‘text’]选取所有具有指定元素并且文本内容是text节点
    /article/div[1]选取属于article子元素的第一个div元素
    /article/div[last()]选取属于article子元素的最后一个div元素
    /article/div[last()-1]选取属于article子元素的倒数第二个div元素
    //div[@lang]选取所有拥有lang属性的div元素
    //div[@lang=‘eng’]选取所有lang属性为eng的div元素
    /div/*选取属于div元素的所有子节点
    //*选取所有元素
    //div[@*]选取所有带属性的title元素

    2.1:读取文件解析节点

    from lxml import html
    etree = html.etree
    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0"><a href="link5.html">a属性</a>
         </ul>
     </div>
    '''
    html=etree.HTML(text) #初始化生成一个XPath解析对象
    result=etree.tostring(html,encoding='utf-8')   #解析对象输出代码
    print(type(html))
    print(type(result))
    print(result.decode('utf-8'))
    

    输出结果:

    #etree会修复HTML文本节点
    <class 'lxml.etree._Element'>
    <class 'bytes'>
    <html><body><div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
             <li class="item-0"><a href="link5.html">a属性</a>
         </li></ul>
     </div>
    </body></html>  # 自动加上了html,body标签
    

    2.2 读取HTML文件进行解析

    html=etree.parse('test.html',etree.HTMLParser()) #指定解析器HTMLParser会根据文件修复HTML文件中缺失的如声明信息
    result=etree.tostring(html)   #解析成字节
    #result=etree.tostringlist(html) #解析成列表
    print(type(html))
    print(type(result))
    print(result)
    

    2.3 获取所有节点

    返回一个列表每个元素都是Element类型,所有节点都包含在其中

    html=etree.parse('test',etree.HTMLParser())
    result=html.xpath('//*')  # //代表获取子孙节点,*代表获取所有
    # result=html.xpath('//li')   # 获取所有子孙节点的li节点
    # result=html.xpath('//li[2]]')   # 获取所有子孙节点第二个li节点
    print(result)   # 总是返回一个列表
    

    2.4 获取子节点

    通过/或者//即可查找元素的子节点或者子孙节点,如果想选择li节点的所有直接a节点,可以这样使用

    result=html.xpath('//li/a')  # 通过追加/a选择所有li节点的所有直接a节点,因为//li用于选中所有li节点,/a用于选中li节点的所有直接子节点a
    

    2.5 获取父节点

    我们知道通过连续的/或者//可以查找子节点或子孙节点,那么要查找父节点可以使用…来实现也可以使用parent::来获取父节点

    from lxml import etree
    from lxml.etree import HTMLParser
    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text,etree.HTMLParser())
    result=html.xpath('//a[@href="link2.html"]/../@class')
    result1=html.xpath('//a[@href="link2.html"]/parent::*/@class')
    print(result)
    print(result1)
    ###############################################################
    ['item-1']
    ['item-1']
    

    2.6 属性匹配

    在选取的时候,我们还可以用@符号进行属性过滤。比如,这里如果要选取class为item-1的li节点,可以这样实现:

    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text,etree.HTMLParser())
    result=html.xpath('//li[@class="item-1"]')
    print(result)
    

    2.7 文本获取

    我们用XPath中的text()方法获取节点中的文本

    text='''
    <div>
        <ul>
             <li class="item-0"><a href="link1.html">第一个</a></li>
             <li class="item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text,etree.HTMLParser())
    result=html.xpath('//li[@class="item-1"]/a/text()') #获取a节点下的内容
    result1=html.xpath('//li[@class="item-1"]//text()') #获取li下所有子孙节点的内容
    print(result)
    print(result1)
    

    2.8 属性获取

    使用@符号即可获取节点的属性,如下:获取所有li节点下所有a节点的href属性

    result=html.xpath('//li/a/@href')  # 获取a的href属性
    result=html.xpath('//li//@href')   # 获取所有li子孙节点的href属性
    

    2.9 属性多值匹配

    如果某个属性的值有多个时,我们可以使用contains()函数来获取

    text1='''
    <div>
        <ul>
             <li class="aaa item-0"><a href="link1.html">第一个</a></li>
             <li class="bbb item-1"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text1,etree.HTMLParser())
    result=html.xpath('//li[@class="aaa"]/a/text()')
    result1=html.xpath('//li[contains(@class,"aaa")]/a/text()')
    print(result)
    print(result1)
    
    #通过第一种方法没有取到值,通过contains()就能精确匹配到节点了
    []
    ['第一个']
    

    2.10 多属性匹配

    另外我们还可能遇到一种情况,那就是根据多个属性确定一个节点,这时就需要同时匹配多个属性,此时可用运用and运算符来连接使用:

    text1='''
    <div>
        <ul>
             <li class="aaa" name="item"><a href="link1.html">第一个</a></li>
             <li class="aaa" name="fore"><a href="link2.html">second item</a></li>
         </ul>
     </div>
    '''
    html=etree.HTML(text1,etree.HTMLParser())
    result=html.xpath('//li[@class="aaa" and @name="fore"]/a/text()')
    result1=html.xpath('//li[contains(@class,"aaa") and @name="fore"]/a/text()')
    print(result)
    print(result1)
    #########################################
    ['second item']
    ['second item']
    

    2.11 XPath中的运算符

    XPath中的运算符

    2.12 按序选择

    有时候,我们在选择的时候某些属性可能同时匹配多个节点,但我们只想要其中的某个节点,如第二个节点或者最后一个节点,这时可以利用中括号引入索引的方法获取特定次序的节点:

    text1='''
    <div>
        <ul>
             <li class="aaa" name="item"><a href="link1.html">第一个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第二个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第三个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第四个</a></li> 
         </ul>
     </div>
    '''
    html=etree.HTML(text1,etree.HTMLParser())
    result=html.xpath('//li[contains(@class,"aaa")]/a/text()') #获取所有li节点下a节点的内容
    result1=html.xpath('//li[1][contains(@class,"aaa")]/a/text()') #获取第一个
    result2=html.xpath('//li[last()][contains(@class,"aaa")]/a/text()') #获取最后一个
    result3=html.xpath('//li[position()>2 and position()<4][contains(@class,"aaa")]/a/text()') #获取第一个
    result4=html.xpath('//li[last()-2][contains(@class,"aaa")]/a/text()') #获取倒数第三个
    print(result)
    print(result1)
    print(result2)
    print(result3)
    print(result4)
    ###########################################
    ['第一个', '第二个', '第三个', '第四个']
    ['第一个']
    ['第四个']
    ['第三个']
    ['第二个']
    

    这里使用了last()、position()函数,在XPath中,提供了100多个函数,包括存取、数值、字符串、逻辑、节点、序列等处理功能,它们的具体作用可参考:

    http://www.w3school.com.cn/xpath/xpath_functions.asp
    

    2.13 节点轴选择

    XPath提供了很多节点选择方法,包括获取子元素、兄弟元素、父元素、祖先元素等,示例如下:

    text1='''
    <div>
        <ul>
             <li class="aaa" name="item"><a href="link1.html">第一个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第二个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第三个</a></li>
             <li class="aaa" name="item"><a href="link1.html">第四个</a></li> 
         </ul>
     </div>
    '''
    html=etree.HTML(text1,etree.HTMLParser())
    result=html.xpath('//li[1]/ancestor::*')  #获取所有祖先节点
    result1=html.xpath('//li[1]/ancestor::div')  #获取div祖先节点
    result2=html.xpath('//li[1]/attribute::*')  #获取所有属性值
    result3=html.xpath('//li[1]/child::*')  #获取所有直接子节点
    result4=html.xpath('//li[1]/descendant::a')  #获取所有子孙节点的a节点
    result5=html.xpath('//li[1]/following::*')  #获取当前子节之后的所有节点
    result6=html.xpath('//li[1]/following-sibling::*')  #获取当前节点的所有同级节点
    ######################
    [<Element html at 0x3ca6b960c8>, <Element body at 0x3ca6b96088>, <Element div at 0x3ca6b96188>, <Element ul at 0x3ca6b961c8>]
    [<Element div at 0x3ca6b96188>]
    ['aaa', 'item']
    [<Element a at 0x3ca6b96248>]
    [<Element a at 0x3ca6b96248>]
    [<Element li at 0x3ca6b96308>, <Element a at 0x3ca6b96348>, <Element li at 0x3ca6b96388>, <Element a at 0x3ca6b963c8>, <Element li at 0x3ca6b96408>, <Element a at 0x3ca6b96488>]
    [<Element li at 0x3ca6b96308>, <Element li at 0x3ca6b96388>, <Element li at 0x3ca6b96408>]
    

    以上使用的是XPath轴的用法,更多轴的用法可参考:http://www.w3school.com.cn/xpath/xpath_axes.asp

    三:xpath实例

    基础版:

    from lxml import html
    from urllib import request
    etree = html.etree
    def parse_page(url):
        headers = {
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)',
        }
        response = requests.get(url, headers = headers)
        text = response.text
        html = etree.HTML(text)
        imgs = html.xpath("//div[@class='page-content text-center']//img[@class!='gif']")
        for img in imgs:
            img_url = img.get('data-original')    # 获取image标签中的data-original属性值
            img_title = img.get('alt')            # 获取image标签中的alt属性值
            img_title = re.sub(r'[\??\.,。!!]', '', img_title)
            img_suffix = os.path.splitext(img_url)[-1]
            filename = img_title + img_suffix
            request.urlretrieve(img_url, 'images/' + filename)
    def main():
        url = 'http://www.doutula.com/photo/list/?page=4'
        parse_page(url)
    
    if __name__ == '__main__':
        main()
    

    多线程版:

    from queue import Queue
    import requests
    from lxml import html
    from urllib import request
    import threading
    
    etree = html.etree
    class Producer(threading.Thread):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
        def __init__(self, page_queue, image_queue, *args, **kwargs):
            super(Producer, self).__init__(*args, **kwargs)
            self.page_queue = page_queue
            self.image_queue = image_queue
        def run(self) -> None:
            while True:
                if self.page_queue.empty(): break
                url = self.page_queue.get() # 队列中的最后一个url
                self.parse_page(url)
        def parse_page(self, url):
            response = requests.get(url, headers=self.headers)
            text = response.content.decode()
            html = etree.HTML(text)
            images = html.xpath("//div[@class='page-content text-center']//img")
            for image in images:
                image_url = image.get('data-original')
                image_name = image_url.split('/')[-1]
                # request.urlretrieve(image_url, 'images/%s' % image_name)
                self.image_queue.put((image_url, image_name))
    class Consumer(threading.Thread):
        def __init__(self, page_queue, image_queue, *args, **kwargs):
            super(Consumer, self).__init__(*args, **kwargs)
            self.page_queue = page_queue
            self.image_queue = image_queue
        def run(self) -> None:
            while True:
                if self.image_queue.empty() and self.page_queue.empty():
                    break
                image_url, image_name = self.image_queue.get()
                request.urlretrieve(image_url, 'images/%s' % image_name)
                print(image_name + ' Downloaded')
    def main():
        page_queue = Queue(10)
        image_queue = Queue(1000)
        for x in range(1,10):
            url = "https://www.doutula.com/photo/list/?page=%s" % x
            page_queue.put(url)
        for x in range(5):
            t = Producer(page_queue, image_queue)
            t.start()
        for x in range(5):
            t = Consumer(page_queue, image_queue)
            t.start()
    if __name__ == '__main__':
        main()
    
    展开全文
  • //div/h1/text() (三) lxml库 lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。 在使用前我们需要在pycharm里安装lxml库。 在终端输入指令即可: pip install lxml -i ...
  • Python lxml库的安装和使用

    千次阅读 2022-03-11 12:35:54
    Python lxml库的安装和使用 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 Xpath 表达式提供了良好的支持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 安装...
  • 1.爬虫是什么所谓爬虫,就是按照一定的规则,自动的从网络中抓取信息的程序或者脚本网络,又被称为网页蜘蛛,网络机器人。万维网就像一个巨大的蜘蛛网,我们的爬虫就是上面的一个蜘蛛,不断的去抓取我们需要的信息。2...
  • lxmlpython的一个解析,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它...
  • python爬虫lxml详解

    千次阅读 2019-04-29 12:25:22
    python爬虫解析HTML也是一项重要的任务,而选择合适的解析器就显得尤为重要了,下面为大家详细解析一下lxml解析, 我信奉的是实践出真知,你看再多语法书不如自己动手敲出来,看看它到底实现的是什么功能,这样总...
  • 本来打算写的标题是XPath语法,但是想了一下Python中的解析库lxml,使用的是Xpath语法,同样也是效率比较高的解析方法,所以就写成了XPath语法和lxml库的用法 XPath 即为 XML 路径语言,它是一种用来确定 XML(标准...
  • python 爬虫中,必然会接触到 HTML 解析。...这时lxml库就派上用场了。这个库的主要优点是易于使用,在解析大型文档时速度非常快,归档的也非常好,并且提供了简单的转换方法来将数据转换为Pyth...
  • Python lxml解析实战应用

    千次阅读 2022-03-11 12:40:38
    下面使用 lxml 抓取猫眼电影 Top100 榜(点击访问),编写程序的过程中,注意与《Python爬虫抓取猫眼电影排行榜》中使用的正则解析方式对比,这样您会发现 lxml 解析是如此的方便。 确定信息元素结构 首先明确要...
  • Python3爬虫利器之lxml解析的安装

    千次阅读 2021-04-26 21:39:29
    lxmlPython的一个解析,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。本节中,我们了解一下lxml的安装方式,这主要从Windows、Linux和Mac三大平台来介绍。1. 相关链接官方网站:...
  • 大家好,上次介绍了BeautifulSoup爬虫入门,本篇内容是介绍lxml模块相关教程,主要为Xpath与lxml.cssselect 的基本使用。 一、lxml介绍 引用官方的解释: lxml XML工具箱是Clibxml2和libxslt的Python绑定 。它的...
  • 【福利+1】lxml库,可以快速的定位特定元素以及节点信息,提取出 HTML、XML 目标数据。在学Python爬虫的老铁们,戳进来看看,说不定对你有用噢~
  • requests 非常适合作为 Python 爬虫入门阶段第一选择,其简单的接口与代码封装,能大幅度降低网络请求代码编写难度,让你专注与目标数据的提取,更有基于高级请求的封装作为提高部分,该完全可以贯穿你的整个爬虫...
  • lxml是一种使用Python编写的,可以迅速、灵活地处理XML和HTML,使用XPath语法来进行文件格式解析。上一篇中我们了解了如何使用XPath找到有效数据具体的定位,但是没有提起如何在Python中使用,那么本文就将Lxml和...
  • 10-python爬虫lxml库

    万次阅读 2020-09-27 23:47:51
    lxml 是一种使用 Python 编写的,可以迅速、灵活地处理 XML ,支持 XPath (XML Path Language) lxml python 官方文档 http://lxml.de/index.html 学习目的 利用上节课学习的XPath语法,来快速的定位 特定元素以及...
  • Python爬虫lxml的xpath二次匹配

    千次阅读 2019-09-10 14:42:52
    Python爬虫lxml的xpath二次匹配 from lxml import etree ''' 在爬取多级分类,并且需要逐级对应时用到 ''' html = ''' <div> <div class="content_box" id="divnewslist"> <ul> <li>...
  • lxml的安装 Windows ...转到http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml下载对应的wheel文件,找到本地安装python版本和系统对应的lxml版本,例如Windows64位、Python 3.7,就选择lxml-4.5.2-cp37-
  • pyhton 3.6 下载32位传送门64位传送门下载的是可执行文件,...lxml库安装两种方法:第一种:打开cmd,输入pip install lxml如果你的脸真的白(像我一样)就可以直接安装成功,但大部分都会出错,那么就用到了第二种...
  • python爬虫教程(6)-lxml解析网页

    千次阅读 2019-02-16 20:17:32
    欢迎来到python爬虫大讲堂,现在开始你的爬虫旅程吧! lxml 上一次我们讲解了BeautifulSoup解析网页,这一次我们来讲讲最后一种解析方式,也就是lxml,它用C语言编写,使用xPath语法。 lxml获取日期 lxml使用xPath...
  • Lxml库Lxml库是基于libxml2的XML解析库的Python库,该模块使用C语言编写,解析速度比BeautifulSoup更快。Lxml库使用Xpath语法解析定位网页数据。1 安装与使用windows系统下,在cmd命令提示框中,输入如下命令:pip ...
  • Pythonlxml库的用法

    千次阅读 2017-03-16 16:15:07
    前言 前面已经学习了requests和beautifulsoup的知识,大家可以看Python中Requests的用法,Python中Beautiful Soup的用法,今天再来学习...lxml是为libxml2和libxslt的一个Python化的绑定。它与众不同的地方是
  • 安装 pip install resquests pip install lxml requests的基本使用
  • lxml并不是Python自带的包,而是为libxml2和libxslt的一个Python化的绑定。它与众不同的地方是它兼顾了这些的速度和功能完整性,以及纯Python API的简洁性,与大家熟知的ElementTreeAPI兼容但比之...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,522
精华内容 16,208
关键字:

python爬虫lxml库