Python爬虫教程

第一章: 初学乍练-Python快速入门

第二章: 初窥门径-从全局把握网络爬虫

第三章: 爬虫数据-网页与JSON

第四章: 爬虫核心-HTTP协议

第五章: 手到擒来-数据的抓包

第六章: 利刃出鞘-HTTP请求库

第七章: 尘埃落定-数据的解析

第八章: 逆向初探-JS逆向

第九章: 爬虫进阶-Selenium, 中间人拦截

第十章:斗转星移-常用的反爬策略及应对方法

首页 > Python爬虫教程 > 第七章: 尘埃落定-数据的解析 > 7.2节:使用lxml解析网页

7.2节:使用lxml解析网页

薯条老师 2021-03-15 07:52:28 235352 0

编辑 收藏

广州番禺Python爬虫小班周末班培训

第四期线下Python爬虫小班周末班已经开课了,授课详情请点击:http://chipscoco.com/?id=232

7.2.1 lxml简介

lxml是什么呢?打开官网来一观究竟:

lxml is the most feature-rich and easy-to-use library for processing XML and HTML in the Python language.

lxml的官网地址:https://lxml.de/ 

 大意为:lxml是一个用Python语言实现的,包含多种特性、易于使用的库,用来处理XML和HTML。在7.1节的内容中,讲到了正则表达式,通过编写正则表达式可以对HTML进行解析。本文介绍的lxml不仅可以解析XML,还可以高效、快速地解析HTML。直接使用已封装好的,成熟稳定的库,可以让程序员对网页的解析处理变得更加简单。

7.2.2安装lxml

进入windows或Linux命令行,在命令行中执行pip install lxml,即可完成lxml的安装。安装完毕以后,进入Python交互模式,执行import lxml,如未抛出任何异常,说明安装成功。

 lxml的安装依赖于libxml2等库,在Linux系统中安装出错时,读者可参考官网的这篇安装教程:https://lxml.de/installation.html

7.2.3 XPath语法

使用lxml解析HTML,需要熟悉XPath语法。XPath是XML路径语言,用来定位XML文档中的节点。XML与HTML在文档结构上是一致的,所以当然也可以使用XPath来定位HTML中的节点。那么什么是文档节点呢?请读者先看下面的HTML代码:

<html>
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <title>薯条老师的官方教程:www.chipscoco.com</title>
</head>
<body>  
</body>
</html>

在上面的代码中,最外层的节点是html,head与body是其子节点,这是一种父子节点的关系。父子节点关系是一种递归的概念,比如某一个子节点也可以是其它节点的父节点,例如在上面的代码中,head节点是html节点的子节点,同时也是meta和title的父节点。

父与子的节点关系很好理解,除了父子节点,还有一种兄弟节点。如果节点间是平级的关系,那么处于这种关系的节点被称为兄弟节点。例如meta节点与title节点就是兄弟节点。

厘清了节点间的关系以后,需要再学习XPath中的路径表达式,以下是XPath中常用的路径表达式符号:

特殊符号

描述

/

表示从根节点位置进行定位,例如/html,表示定位根节点html

//

以匹配的当前节点作为起始节点,例如//div,表示定位文档中的所有div节点

.

匹配当前节点

..

匹配父节点

@

属性选择器,匹配包含某属性的节点,例如//a[@href='www.chipscoco.com'],表示定位文档中所有href属性为www.chipscoco.com的a节点

*

通配符,用来匹配任何节点,例如//div/*,用来定位div节点下的所有节点

|

连接符,用来连接路径表达式,例如//h1 | //p,用来定位所有h1节点以及所有p节点

and,or

逻辑运算符,用来进行逻辑判断。例如a[@href='www.chipscoco.com' and @class='nav'],用来定位文档中所有href属性为www.chipscoco.com且class属性为nav的a节点

当需要对定位的节点进行更细粒度的筛选时,可以使用XPath中的谓语。谓语被定义在[]中,[]中可以输入位置索引,表示定位某一个具体位置的元素,例如//div/img[1],表示选择所有div节点下的第一个img节点。以下是常用的谓语:

谓语

描述

[位置索引]

位置索引从0开始编号,表示第一个元素,例如//div/p[0],表示选择所有div节点下的第一个p节点。

也可以使用内置方法来获得指定位置的节点,比如last()用来获取最后一个元素,last()-1表示倒数第二个,以此类推。position方法则用来指定某一段范围,常与关系运算符结合使用,例如//div/p[position() < 2],用来选择所有div节点下的前2个p节点。

[属性选择]

即在[]中使用属性选择器,例如//div/a[href]表示选择div节点下的包含href属性的所有a节点。//div/a[href='www.chipscoco.com'],表示选择文档中div节点下的href属性值为www.chipscoco.com的所有a节点。

[模糊匹配]

使用contains,starswith等方法来进行模糊查找。contains表示选择属性包含某内容的节点,starswith则表示选择属性中以某关键字作为前缀的节点。例如//input[contains(@name,'se')],表示选择所有name属性中包含se的 input节点。

以上是常用的路径表达式符号及谓语,在实际使用中,会将各种路径符号和谓语组合成一个复杂的路径表达式,以对网页内容进行提取。定位到节点以后,再通过@符号来提取出属性值,通过text()方法来提取出标签文本。例如//div/a/@href,用来提取出所有div节点下的a节点的herf属性值。//div/a/text()用来提取出所有div节点下的a节点的文本。

7.2.4 解析HTML

熟悉了XPath的语法以后,现在通过lxml来对HTML进行解析。使用lxml对HTML进行解析,请读者按照以下3个步骤进行操作:

①  从lxml中导入etree模块

②  执行etree模块的HTML方法构建etree的Element对象

HTML方法的常用参数:HTML(text),text表示HTML文本。

③ 通过Element对象的xpath方法来解析HTML

代码实例1-解析所有title标签的文本:

from lxml import  etree
HTML= """
<html>
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <title>薯条老师的官方教程:www.chipscoco.com</title>
</head>
<body>  
</body>
</html>
"""

etree = etree.HTML(HTML)
o = etree.xpath("//title/text()")
print(o)

输出结果:

['薯条老师的官方教程:www.chipscoco.com']

代码实例2-解析所有div标签下的所有img标签的src属性

from lxml import  etree

HTML=  """
<html>
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <title>薯条老师的官方教程:www.chipscoco.com</title>
</head>
<body> 
    <div> 
        <img src="/media/images/logo.png" />
        <ul>
           <li><img  src="http://justtest.com/one.jpg"/></li>
        </ul>
</div>
<ul>
    <li> <a href="www.chipscoco.com">薯条老师的官方教程</a></li>
    <li> <a href="www.chipscoco.cn">橙子在线编程</a></li>
</ul>
</body>
</html>
"""


etree = etree.HTML(HTML)
o = etree.xpath("//div//img/@src")
print(o)

输出结果:

['/media/images/logo.png', 'http://justtest.com/one.jpg']

注意,以上代码中的路径表达式为//div//img,表示获取div节点下的所有img节点,包括所有后代节点。如果路径表达式为//div/img,那么只能匹配到div节点下的img子节点。读者可以将代码中的路径表达式改为//div/img/@src,那么输出的只是['/media/images/logo.png']。

代码实例3-解析ul节点下的li子节点的a

from lxml import  etree
HTML=  """
<html>
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <title>薯条老师的官方教程:www.chipscoco.com</title>
</head>
<body> 
<ul>
    <li> <a href="www.chipscoco.com">薯条老师的官方教程</a></li>
    <li> <a href="www.chipscoco.cn">橙子在线编程</a></li>
<li> <a href="www.shadows.com">侠影七三</a></li>
<li> <img src="/media/images/cover.png" /></li>
</ul>
</body>
</html>
"""

etree = etree.HTML(HTML)
li_container = etree.xpath("//ul/li")

for li in li_container:
    # 列表中的每一个元素均为Element对象
    # xpath中的.表示当前节点
    o = li.xpath("./a[contains(@href, 'chipscoco')]/@href")
    print(o) if o else _

输出结果:

['www.chipscoco.com']

['www.chipscoco.cn']

以上的实例代码演示的是比较基础的操作,更复杂的解析表达式无非是将XPath中的路径表达式进行组合。读者需要先熟练掌握最基础的操作,然后再根据不同的需求来进行灵活组合。HTML文档数据,读者可以根据第六章中学过的知识,调用requests等库来对指定页面进行请求。

7.2.5 高薪就业班

(1) Python后端工程师高薪就业班,月薪10K-15K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪10K-20K, 免费领取课程大纲
(4) Python大数据工程师就业班,月薪12K-25K,免费领取课程大纲

扫码免费领取学习资料:


欢迎 发表评论: