xpath语法和lxml模块
什么是xpath
xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对文档的属性和值进行遍历
Xpath开发工具
- Chrome插件XPath Helper
- Firefox插件XPath Checker
选取节点
xpath使用路径表达式来选取XML文件中的节点或者节点集。这些路径表达式和我们常规的电脑系统中看到的路径类似。
| 表达式 | 描述 | 示例 | 结果 |
|---|---|---|---|
| nodename | 选取此节点的所有子节点 | bookstore | 选取div下面的所有子节点 |
| / | 如果是最前面,代表从根节点选取,否则选择某节点的下的某个节点 | /div | 选取根元素下面的所有div节点 |
| // | 从全局节点的某一个节点,随便哪个位置 | //div | 从全局节点找到所有div节点 |
| @ | 选取某个节点的属性 | //div[@class] | 选择所有div节点的class属性 |
谓语
谓语通常用来查找某个特定的节点或者包含指定值得节点,被镶嵌在方括号中。
在下面的表格中,我们列出了一些带有谓语的表达式,以及表达式结果:
| 表达式 | 描述 |
|---|---|
| /div/span[1] | 选取div下面的第一个span标签 |
| /div/span[last()] | 选取div下面的倒数第一个span标签(最后一个) |
| /div/span[last()-1] | 选取div下面的倒数第二个span标签 |
| /div/span[position()<3] | 选取div下面的前2个span标签 |
| /div[@class] | 选取有class属性的div标签 |
| /div[@id=’psw‘] | 选取id属性值为psw的div标签 |
通配符
*和.标示通配符:
| 通配符 | 描述 | 示例 | 结果 |
|---|---|---|---|
| * | 匹配任一节点标签 | /div/* | 选取div下面的所有字节点 |
| 匹配节点的任何属性 | //div[@*] | 选取带所有属性的div标签 |
选取多个路径
通过在路径表达式中使用"运算符",可以选取若干个路径,示例如下:
//div/span | span/p
#选取div下面的所有span标签和span下面的p标签。
xpath语法
使用方式
- 使用
//获取整个页面元素,再用标签名最后@加属性的值来选取 - 如果选取节点下面的文本信息就用
/text() - 选取节点链接(href)的信息就用
/@href -
/如果不在前面就标示所有子节点,而//不在最前面则代表的是下面的所有子孙节点。
示例如下:
'//div[@class="job-detail"]/p/text()'
'//div[@class="job-detail"]/a/@href'
lxml模块用法
python语言用xpath方法获取HTML所需数据,用到的是lxml模块,下面我们来介绍一下lxml模块的用法:
如果已经安装python,通过pip install方式导入lxml包,进入cmd命令行,输入
pip install lxml回车,即可安装lxml包如果pip安装不成功,可以浏览官方地址下载lxml模块,地址:https://lxml.de/index.html,也可以在该网页浏览lxml的具体用法。
-
安装后我们最常用到的是用lmxl.etree,然后用etree的HTML方法来把response的字符串文件转换成HTML,在使用Xpath来获取元素以及元素属性值。
示例如下:
from lxml import etree
content='''<div class="job-detail">
<p>岗位要求:</p>
<p>1. 熟练掌握python基础语法</p>
<p>2. 熟练使用django restframework框架</p>
<p>3. 熟练使用pythton redis mysql MongoDB操作</p>
<p>4. 熟练使用celery异步框架</p>
<p>5. 熟练使用linux操作系统 </p>
<p>6. 有运维工作经验优先</p>
<p>7. 熟练使用vue框架,有前端html、JS等相关经验</p>
<p>8. 至少使用DRF 和VUE 有一个完整的项目经验</p>
<p>三年工作经验以上优先</p>
</div>'''
elm=etree.HTML(content)
job_detail=elm.xpath('//div[@class="job-detail"]/p/text()')
job_detail="".join(job_detail)
print(job_detail)
#输出结果为:
#岗位要求:1. 熟练掌握python基础语法2. 熟练使用django restframework框架3. 熟练使用pythton redis mysql MongoDB操作4. 熟练使用celery异步框架5. 熟练使用linux操作系统 6. 有运维工作经验优先7. 熟练使用vue框架,有前端html、JS等相关经验8. 至少使用DRF 和VUE 有一个完整的项目经验三年工作经验以上优先
使用lxml解析HTML方法
lxml不仅可以解析文本也可以解析html文件,其主要用到的方法为:
-
解析文本字符串,用到的方法为
lxml.etree.HTML()将文本转换成element类,然后在用XPath提取我们想要的内容,示例代码如下:job_detail=lxml.etree.HTML(content).xpath('//div[@class="job-detail"]/p/text()') -
lxml也可以解析HTML文件,用到方法为
lxml.parse()括号内为HTML文件,示例代码如下:job_detail=lxml.parse('e:\lagou.html').xpath('//div[@class="job-detail"]/p/text()') -
如果碰到一些不规范的
HTML代码就会解析错误,这时候就需要自己创建HTML解析器,示例代码如下:paser=lxml.etree.HTMLparser(encodeing="utf-8") job_detail=lxml.parse('e:\lagou.html',parser=paser).xpath('//div[@class="job-detail"]/p/text()')
job_detail=lxml.parse('e:\lagou.html').xpath('//div[@class="job-detail"]/p/text()')
lxml练习
练习:获取糗事百科段子第一页的所有段子
from lxml import etree
import requests
response=requests.get('https://www.qiushibaike.com/text/page/1/')
elm=etree.HTML(response.text)
duanzidivs = elm.xpath('//div[@class="col1 old-style-col1"]/div')
duanzis=[]
for duanzidiv in duanzidivs:
author=duanzidiv.xpath('.//h2/text()')
author="".join(author).strip()
content=duanzidiv.xpath('.//div[@class="content"]//text()')
content=''.join(content).strip().replace('\n','').replace('查看全文','')
duanzis.append({'作者':author,'段子':content})
print(duanzis)
print(len(duanzis))