xpath的基础使用
一.xpath简介
XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
- XPath 使用路径表达式在 XML 文档中进行导航
- XPath 包含一个标准函数库
- XPath 是 XSLT 中的主要元素
- XPath 是一个 W3C 标准
`节点
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。
xpath比美丽汤更通用,在各语言的xpath中都可以使用,scrapy框架也是内置了一个xpath,而美丽汤只能在python中使用.
二、xpath语法
1.选取节点
表达式 |
描述 |
实例 |
|
nodename |
选取nodename节点的所有子节点 |
xpath('//div') |
选取了div节点的所有子节点 |
/ |
从根节点选取 |
xpath('/div') |
从根节点上选取div节点 |
// |
选取所有的当前节点,不考虑他们的位置 |
xpath('//div') |
选取所有的div节点 |
. |
选取当前节点 |
xpath('./div') |
选取当前节点下的div节点 |
.. |
选取当前节点的父节点 |
xpath('..') |
回到上一个节点 |
@ |
选取属性 |
xpath('//@calss') |
选取所有的class属性 |
2、谓语
谓语被嵌在方括号内,用来查找某个特定的节点或包含某个特定的值的节点,因为所有xpath解析返回值为一个列表
xpath的索引从1开始
表达式 |
结果 |
xpath('/body/div[1]') |
选取body下的第一个div节点 |
xpath('/body/div[last()]') |
选取body下最后一个div节点 |
xpath('/body/div[last()-1]') |
选取body下倒数第二个div节点 |
xpath('/body/div[positon()<3]') |
选取body下前两个div节点 |
xpath('/body/div[@class]') |
选取body下带有class属性的div节点 |
xpath('/body/div[@class="main"]') |
选取body下class属性为main的div节点 |
xpath('/body/div[price>35.00]') |
选取body下price元素值大于35的div节点 |
3、通配符
Xpath通过通配符来选取未知的XML元素
表达式 |
结果 |
xpath('/div/*') |
选取div下的所有子节点 |
xpath('/div[@*]') |
选取所有带属性的div节点 |
4、逻辑运算
使用“|”或者and运算符可以选取多个路径
表达式 |
结果 |
xpath('//div|//table') |
选取所有的div和table节点 |
xpath(//a[@href="" and @class="du"]) |
选取同时具href="",class='du'的a标签 |
5、Xpath轴
轴可以定义相对于当前节点的节点集
轴名称 |
表达式 |
描述 |
ancestor |
xpath('./ancestor::*') |
选取当前节点的所有先辈节点(父、祖父) |
ancestor-or-self |
xpath('./ancestor-or-self::*') |
选取当前节点的所有先辈节点以及节点本身 |
attribute |
xpath('./attribute::*') |
选取当前节点的所有属性 |
child |
xpath('./child::*') |
返回当前节点的所有子节点 |
descendant |
xpath('./descendant::*') |
返回当前节点的所有后代节点(子节点、孙节点) |
following |
xpath('./following::*') |
选取文档中当前节点结束标签后的所有节点 |
following-sibing |
xpath('./following-sibling::*') |
选取当前节点之后的兄弟节点 |
parent |
xpath('./parent::*') |
选取当前节点的父节点 |
preceding |
xpath('./preceding::*') |
选取文档中当前节点开始标签前的 |
preceding-sibling |
xpath('./preceding-sibling::*') |
选取当前节点之前的兄弟节点 |
self |
xpath('./self::*') |
选取当前节点 |
6、功能函数(模糊匹配)
使用功能函数能够更好的进行模糊搜索
函数 |
用法 |
解释 |
starts-with |
xpath('//div[starts-with(@id,"ma")]') |
选取id值以ma开头的div节点 |
contains |
xpath('//div[contains(@id,"ma")]') |
选取id值包含ma的div节点 |
and |
xpath('//div[contains(@id,"ma") and contains(@id,"in")]') |
选取id值包含ma和in的div节点 |
text() |
xpath('//div[contains(text(),"ma")]') |
选取节点文本包含ma的div节点 |
7.取属性和文本
@ | //div[@class="tang"]//li[2]/a/@href | 取标签的的href属性值 |
text() | //div[@class="song"]/p[1]/text() | 取p[1]的所有属性值 |
text() | //div[@class="tang"]//text() | 取div标签的所有文本值,包括子标签的 |
8.通过text()确定标签
选取文本是'>'的a标签
xpath('//a[text()=">"]')
9.string(.)提取所有文本
html3 = '''
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test3">
我左青龙,
<span id="tiger">
右白虎,
<ul>上朱雀,
<li>下玄武。</li>
</ul>
老牛在当中,
</span>
龙头在胸口。
</div>
</body>
</html>
'''
#如果使用一般的办法,就会出现获取到的数据不完整的情况
selector = lxml.html.fromstring(html3)
# content_1 = selector.xpath('//div[@id="test3"]/text()')
# for each in content_1:
# print(each) # 使用string(.)就可以把数据获取完整
data = selector.xpath('//div[@id="test3"]')[0]
info = data.xpath('string(.)')
print(info) #####或者使用这种情况
t=etree.HTML(html3)
res = t.xpath("//div[@id='test3']//text()")
print(res)
10.text_content()
最开始对html文本使用 etree.HTML(html)解析,得到Element对象。 from lxml import etree str=""" <div>
<a href="xxxx">123</a>
<a href="xxxx">45</a>
<div> """ root= etree.HTML(str) root.xpath("//div//text()") #发现并没有直接获取12345文本方法 #后来网上调查发现lxml操作html有一个专门的html模块html,然后找到了解决该问题的关键方法text_content(),这个方法在上面的写法中是不存在的于是解决方案如下。 from lxml import html root = html.fromstring('''<div><a href="xxxx">123</a><a href="xxxx">45</a><div>''') root.xpath("//div").text_content()
三.使用流程
xpath数据解析流程:
1.pip install lxml
2.导包:from lxml import etree
3.实例化一个etree对象(将页面数据加载到该对象)
- 本地文件:tree = etree.parse(文件名) tree.xpath("xpath表达式") ===>本地文件指的是包打开的网页另存为到本地的文件
- 网络数据:tree = etree.HTML(网页内容字符串) tree.xpath("xpath表达式")
4.调用etree中的xpath函数结合着xpath表达式进行数据解析操作
看一个例子(爬取58)
import requests
from lxml import etree headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER'
}
url='https://sz.58.com/ershoufang/?PGTID=0d200001-0000-4229-cd25-6936558931c6&ClickID=1'
#拿到页面源码数据的text
page_text=requests.get(url=url,headers=headers).text
#把页面源码数据作为参数实例一个etree对象
tree=etree.HTML(page_text) #用xpath进行解析
#xpath表达式的作用:xpath表达式如果作用到页面源码中,可以将页面源码中指定的标签进行定位.
#所有xpath解析返回值为一个列表
#可以对局部对象在进行xpath,但是路径要记得要变成./
li_list=tree.xpath('//ul[@class="house-list-wrap"]/li') f=open('./xpath-58.txt','w',encoding='utf-8')
for li in li_list:
title=li.xpath('./div[2]/h2/a/text()')[0]#xpath返回的是一个列表,即使解析对象只有一个
total_price=li.xpath('./div[3]/p[1]//text()')#返回两个值直接返回
total_price=''.join(total_price) f.write(title+':'+total_price+'\n')
f.close() #这边只爬取了第一页,如想要爬取其他页面,只要去改一下页码参数,进行一个循环即可
主要几点:
1.获取文本
- a/text() 获取a下文本
- a//text() 获取a下面的所有文本
- a[text()='下一页']
2.@符号
- a/@href
- div[@class='detail']
- div[@id='content']
3.//
- 任意位置开始选择
xpath的基础使用的更多相关文章
- xpath的基础实例
本文分为路径表达式和常用函数两部分,整理自火车浏览器官方教程-火车浏览器之Xpath讲解. 小提示:可以使用火狐浏览器.我用的是火狐浏览器+firebug+firepath来进行调试,调试界面是这样的 ...
- XML学习笔记6——XPath语言
在上一篇笔记的结尾,我们接触到了两个用于选择XML文档中特定范围的元素<selector>和<field>,这两个元素的取值都是XPath表达式,那么,什么是XPath呢?简单 ...
- XML相关的安全漏洞-XXE,XPATH小结
0x00前言: 本文主要小结以下php下的xpath查询xml结构的漏洞利用和XXE漏洞利用 xml是可扩展标记语言,它被设计出来是为了存储传输数据的. 它的结构是树形结构,并且标签要成对出现比如下面 ...
- Xpath语法-爬虫(一)
前言 这一章节主要讲解Xpath的基础语法,学习如何通过Xpath获取网页中我们想要的内容;为我们的后面学习Java网络爬虫基础准备工作. 备注:此章节为基础核心章节,未来会在网络爬虫的数据解析环节经 ...
- 2017-2018-2 20155303『网络对抗技术』Exp9:Web安全基础
2017-2018-2 『网络对抗技术』Exp9:Web安全基础 --------CONTENTS-------- 一.基础问题回答 1.SQL注入攻击原理,如何防御? 2.XSS攻击的原理,如何防御 ...
- Scrapy下xpath基本的使用方法
Scrapy是基于python的开源爬虫框架,使用起来也比较方便.具体的官网档:http://doc.scrapy.org/en/latest/ 之前以为了解python就可以直接爬网站了,原来还要了 ...
- (数据科学学习手札61)xpath进阶用法
一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外(可参考我之前写的(数据科学学习手札50)基于P ...
- XPath简介
参考视频: https://www.bilibili.com/video/av49809274/?p=22 一,什么是XPATH? xpath(xml path language)是一门在xml和 ...
- xpath进阶用法
一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外xpath中还存在着非常之多的进阶用法,本文将对 ...
随机推荐
- VS2013中,将Qt的GUI程序改为控制台程序
在Visual studio 中创建QT GUI程序是不带Console的,但是调试时候常常需要查看打印信息,可以通过如下设置显示控制台 方法一.在vs中直接创建控制台程序方法二.当你通过设置你的应用 ...
- SingletonPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- EZOJ #79
传送门 分析 在经过若干次操作之后一定会产生一堆环 而我们又发现从一个点到另一个点实际可以经过所有环 于是问题就转换成了$k_1s_1 + k_2s_2 + ... + len = t$ 其中$s_i ...
- noi.ac day6t1 queen
传送门 分析 我就是个BT...... 直接排序后开数组记录每条线上的信息,注意由于每个点只会影响前面第一个点和后面第一个点,所以记录每条线的前一个点就行了. 代码 #include<iostr ...
- Android调试之Logcat
转贴 http://www.cnblogs.com/adison/p/4264284.html 在Android开发过程中,总免不了要调试,无论是Debug,还是Android自带的Logcat,抑 ...
- Gremlin:图遍历语言
Gremlin简介 Gremlin是Apache TinkerPop 框架下的图遍历语言.Gremlin是一种函数式数据流语言,可以使得用户使用简洁的方式表述复杂的属性图(property graph ...
- 《Head First Servlets & JSP》-5-属性和监听
Servlet初始化参数 在DD文件(web.xml)中 Servlet参数在/参数下: 在Servlet代码中 在Servlet初始化之前不能使用Servlet初始化参数 一旦有了一个Servlet ...
- Android的性能优化
ArrayList和Vector ArrayList和Vector都是内部以数组实现的List,它们两唯一的区别就是对多线程的支持,ArrayList是线程不安全的,而Vector内部对大多数方法都做 ...
- 遍历一个二维数组的简便方法(减少foreach次数)
在一些特定场合可以使用下, 还是有局限性 输出结果 : 另一种场景 : 输出结果 : 更复杂的场景 : 输出结果 :
- pandas-如何得到某一个值所在的行
df[df['列名'].isin([相应的值])]