网络知识 娱乐 100天精通Python(爬虫篇)——第45天:lxml库与Xpath提取网页数据

100天精通Python(爬虫篇)——第45天:lxml库与Xpath提取网页数据

在这里插入图片描述

文章目录

  • 每篇前言
  • 一、爬虫提取网页数据的流程图
  • 二、lxml库
    • 1. 下载安装
    • 2. 解析HTML网页
  • 三、Xpath介绍
    • 1. 选取节点
    • 2. 谓语
    • 3. 选取未知节点
    • 4. 选取若干路径
    • 5. Chrome插件 XPath Helper安装使用
    • 6. Xpath实战

每篇前言

  • 🏆🏆作者介绍:Python领域优质创作者、华为云享专家、阿里云专家博主、2021年CSDN博客新星Top6

  • 🔥🔥本文已收录于Python全栈系列专栏:《100天精通Python从入门到就业》
  • 📝​📝​此专栏文章是专门针对Python零基础小白所准备的一套完整教学,从0到100的不断进阶深入的学习,各知识点环环相扣
  • 🎉🎉订阅专栏后续可以阅读Python从入门到就业100篇文章还可私聊进两百人Python全栈交流群(手把手教学,问题解答); 进群可领取80GPython全栈教程视频 + 300本计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
  • 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!

在这里插入图片描述
在这里插入图片描述

一、爬虫提取网页数据的流程图

在这里插入图片描述

二、lxml库

lxml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据;,是一款高性能的python HTML、XML解析器,也可以利用XPath语法,来定位特定的元素及节点信息

1. 下载安装

1. window电脑点击win键+ R,输入:cmd

在这里插入图片描述

2. 安装lxml,输入对应的pip命令pip install lxml,我已经安装过了出现版本就安装成功了

在这里插入图片描述

2. 解析HTML网页

主要使用的lxml库中的etree类

案例1解析HTML字符串

from lxml import etree

text = '''

    
无羡
20
四川
'''
# 开始初始化 html = etree.HTML(text) # 这里需要传入一个html形式的字符串 print(html) print(type) # 将字符串序列化为html字符串 result = etree.tostring(html).decode('utf-8') print(result) print(type(result))

输出结果:

<Element html at 0x1f7fa7f2a80>
<class 'type'>
<html><body>
    <div class="key">
        <div class="name">&#26080;羡
<div class="age">20</div> <div class="address">&#22235;川
</div> </body></html> <class 'str'>

案例2读取并解析HTML文件

创建一个html文件
在这里插入图片描述

from lxml import etree

# 将html文件进行读取
html = etree.parse('1.html')

# 将html内容序列化
result = etree.tostring(html).decode('utf-8')
print(result)
print(type(result))
html = etree.HTML(result)  # 这里需要传入一个html形式的字符串
print(html)
print(type)

输出结果:

<html><body>
    <div class="key">
        <div class="name">&#26080;羡
<div class="age">20</div> <div class="address">&#22235;川
</div> </body></html> <class 'str'> <Element html at 0x17dffaa4c40> <class 'type'>

lxml库掌握以上内容即可!

三、Xpath介绍

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

1. 选取节点

最常用的路径表达式:

表达式说明
nodename选取此节点的所有子节点。
/从根节点选取。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
..选取当前节点的父节点。
@选取属性。

案例:

表达式说明
bookstore选取 bookstore 元素的所有子节点。
/bookstore选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book选取属于 bookstore 的子元素的所有 book 元素。
//book选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang选取名为 lang 的所有属性。

2. 谓语

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

路径表达式说明
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

3. 选取未知节点

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

通配符说明
*匹配任何元素节点。
@*匹配任何属性节点。
node()匹配任何类型的节点。

案例:

路径表达式说明
/bookstore/*选取 bookstore 元素的所有子元素。
//*选取文档中的所有元素。
html/node()/meta/@*选择html下面任意节点下的meta节点的所有属性
//title[@*]选取所有带有属性的 title 元素。

4. 选取若干路径

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

案例:

在这里插入图片描述

5. Chrome插件 XPath Helper安装使用

免费下载地址:Chrome插件Xpath_helper.zip

一. 安装

在这里插入图片描述

二、使用:

6. Xpath实战

新建一个hello.html文件:

<!-- hello.html -->

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

1. 获取所有的

  • 标签

    from lxml import etree
    
    html = etree.parse('hello.html')
    print(type(html))  # 显示etree.parse() 返回类型
    
    result = html.xpath('//li')
    
    print(result)  # 打印
  • 标签的元素集合 print(len(result)) print(type(result)) print(type(result[0]))
  • 输出结果:

    <type 'lxml.etree._ElementTree'>
    [<Element li at 0x1014e0e18>, <Element li at 0x1014e0ef0>, <Element li at 0x1014e0f38>, <Element li at 0x1014e0f80>, <Element li at 0x1014e0fc8>]
    5
    <type 'list'>
    <type 'lxml.etree._Element'>
    

    2. 继续获取

  • 标签的所有 class属性

    from lxml import etree
    
    html = etree.parse('hello.html')
    result = html.xpath('//li/@class')
    
    print(result)
    

    输出结果:

    ['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
    

    3. 继续获取

  • 标签下hre 为 link1.html 标签

    from lxml import etree
    
    html = etree.parse('hello.html')
    result = html.xpath('//li/a[@href="link1.html"]')
    
    print(result)
    

    输出结果:

    [<Element a at 0x10ffaae18>]
    

    4. 获取

  • 标签下的所有 标签

    from lxml import etree
    
    html = etree.parse('hello.html')
    
    #result = html.xpath('//li/span')
    #注意这么写是不对的:
    #因为 / 是用来获取子元素的,而  并不是 
  • 的子元素,所以,要用双斜杠 result = html.xpath('//li//span') print(result)
  • 输出结果:

    [<Element span at 0x10d698e18>]
    

    5. 获取

  • 标签下的标签里的所有 class

    from lxml import etree
    
    html = etree.parse('hello.html')
    result = html.xpath('//li/a//@class')
    
    print(result)
    

    输出结果:

    ['blod']
    

    6. 获取最后一个

  • href

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

    输出结果:

    ['link5.html']
    

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

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

    输出结果:

    fourth item
    

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

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

    输出结果:

    span