爬虫之xpath语法和xml模块

xpath简介

什么是xpath?

xpath(xml path language)是一门在xml和html文档查找信息的语言,可用来在xml和html文档中对元素和属性进行遍历。

xpat开发工具

  • 谷歌游览器插件Xpath Helper。
  • Firefox插件 Try Xpath

xpath语法

选取节点
xpath选取路径表达式来选取xml文档的节点和节点集。
表格1

表达式描述示例结果
nodename选取此节点的所有子节点bookstore选取bookstore下所有子节点
/如果在最前面就表示从根节点选取。否则选取某节点下的某个节点/bookstore选取bookstore下所有子节点
@选取某个节点属性//book[@price]选取所有拥有price属性的book节点。

谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号里。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果,注意在xpath下标从1开始。

                      表格2 
路径表达式描述
/bookstore/book[1]选取bookstore下的第一个子元素
/bookstore/book[last()]选取bookstore下的最后一个子元素
/bookstore/book[position()< 3]选取bookstore下的前面两个子元素
//book[@price]选取拥有price属性的book节点
//book[@price=10]选取所有price属性等于10的book节点

通配符
表示通配符

                                  表格3 
通配符描述示例结果
*匹配任意节点/bookstore/*选取bookstore下的所有子元素
@*匹配节点中的任意属性//book[@* ]选取所有带有属性的book元素

选取多个路径
通过使用"|"运算符,可以选取若干个路径。
实例如下:

//bookstore/book | //book/title
选取所有book元素以及book元素下所有的title元素

运算符

                                      表格4
运算符描述示例返回值
div除法8div42
=等于price=11如果price是9.8则返回ture,否则返回false
!=不等于price!=112
<小于price<11如果price是9.8则返回ture,否则返回false
>大于price>11如果price是12则返回ture,否则返回false
<=小于等于price<=11如果price是1则返回ture,如果price是8则返回false
>=大于等于price>=11如果price是12则返回ture,如果price是8则返回false
orprice>11 or price<5如果price是12则返回ture,如果price是6则返回false
andprice>11 and price<15如果price是12则返回ture,如果price是8则返回false

xpath注意事项

  1. 谓语的下标从1开始
  2. //和/的区别。
    //选取的是所有子孙节点;/选取的是直接字节点
  3. contains:有时候某个属性包含多个值,那么可以使用"contains"函数。实例代码如下:
//div[contains(@class,'job_detail')]

Lxml库

lxml是一个html/xml的解析器,主要的功能是如何解析和提取HTML/xml数据。
lxml安装
可使用pip安装:pip install lxml
如果出现安装错误,则需要将目标路径写上

pip install --target=d:\python\python37\lib\site-packages lxml

基本使用:

可以利用lxml来解析html代码,并且在解析html代码时如果不规范,会自动补全。示例代码如下:

#使用lxml的etree库
#encoding utf-8
from lxml import etree

text="""
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>百度招聘</title>
    <meta name="description" content="百度官方招聘平台-诚挚邀请来自社会,校园,实习生,海外的各界精英了解百度,加入百度。百度,招最好的人,给最大的空间,看最后的结果,让优秀人才脱颖而出。">
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Cache-Control" content="no-store" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
    <meta name="baidu-site-verification" content="OP8Pm08nAE" />
    <link rel="shortcut icon" href="images/favicon-ignore.ico" type="image/x-icon" />
    <link rel="icon" href="images/favicon-ignore.ico" type="image/x-icon" />

    <link rel="stylesheet" href="src/_common/css/app.min.css"/>

    <!--[if lt IE 9]>
        <script src="vendor/es5-shim/es5-shim.min.js"></script>
        <script src="vendor/es5-shim/es5-sham.min.js"></script>
        <script src="vendor/html5shiv/dist/html5shiv.js"></script>
    <![endif]-->

</head>
<body>
    <div class="wrap">
        <div class="header"></div>
        <div class="body"></div>
    </div>
    <div class="footer"></div>
    <script src="lib/requirejs/require.js" data-main="src/entry"></script>
    <!-- Baidu Share -->
    <script>
        window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":[],"bdPic":"","bdStyle":"1","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='scripts/share.min.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
    </script>
    <!-- Baidu Tongji -->
    <script type="text/javascript">
    var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
    document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F50e85ccdd6c1e538eb1290bc92327926' type='text/javascript'%3E%3C/script%3E"));
    </script>

</body>
</html>

"""
def parse_text():
    html = etree.HTML(text)
    print(etree.tostring(html, encoding='utf-8').decode('utf-8'))
def parse_file():
    html=etree.parse("renrer.html")#直接使用parse会报错,说明html不规范需要自己创建解析器
    print(etree.tostring(html, encoding='utf-8').decode('utf-8'))
def parse_lagou_file():
    parse=etree.HTMLParser(encoding='utf-8')
    html=etree.parse("renrer.html",parser=parse)
    print(etree.tostring(html,encoding='utf-8').decode('utf-8'))
if __name__=='__main__':
    parse_lagou_file()


使用lxml解析html代码

  1. 解析html字符串:使用’lxml.etree.HTML’
  2. 解析html文件:使用’lxmle.tree.parse’进行解析,这个
    函数默认使用的是’xml’解析器。所以碰到一些不规范的’HTML’的代码时会出现错误
    这个时候就需要自己创建解析器。

lxml结合xpath

  1. 使用’xpath’语法,应该使用’element.xpath’方法。来执行xpath的选择。
    代码如下:
trs=html.xpath("//tr[position()>1]")
  1. 获取某个标签属性
a=html.xpath("//a/@href")
#获取a便签的href属性对应的值
  1. 获取文本,是通过’xpath’中的’text()'函数。示例代码如下:
text=html.xpath(".//tr[4]/text()")
  1. 在某个标签下,在执行xpath函数,获取这个标签的子孙元素
    那么应该在//前加点,代表是在当前元素下获取

lxml+xpath爬取豆瓣电影实例

import requests                                                                                                                              
from  lxml import etree                                                                                                                      
#第一步爬取豆瓣网页数据                                                                                                                                 
url="https://movie.douban.com/cinema/nowplaying/shanghai/"                                                                                   
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"} 
                                                                                                                                             
                                                                                                                                             
response=requests.get(url,headers=header)                                                                                                    
reqt=response.text                                                                                                                           
#print(response.text)                                                                                                         #第二步处理数据                                                        
                                                                 
html=etree.HTML(reqt)                                            
ul=html.xpath("//ul[@class='lists']")[0]                         
lis=ul.xpath("./li")                                             
movies=[]                                                        
for li in lis:                                                   
    title=li.xpath("@data-title")[0]                             
    score=li.xpath("@data-score")[0]                             
    release=li.xpath("@data-release")[0]                         
    duration=li.xpath("@data-duration")[0]                       
    href=li.xpath(".//li[@class='poster']/a/@href")[0]           
    movie={                                                      
        'title':title,                                           
        'score':score,                                           
        'release':release,                                       
        'duration':duration,                                     
        'href':href                                              
    }                                                            
    movies.append(movie)                                         
                                                                 
print(movies)                                                    
#print(etree.tostring(ul,encoding='utf-8').decode("utf-8"))      
                                                                 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值