1. 定义与使用逻辑
1.1 定义
XPath 是一门在 XML 文档中查找信息、搜索内容的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。其中,html 是xml 的一个子集。
1.2 逻辑
一般按照以下顺序
#1、导入模块
from lxml import etree
#2、将HTML文件解析成 Xpath对象
html= etree.HTML(text)
#3、调用Xpath解析对象的xpath 方法, 对内容进行解析
2. 使用
2.1 下载模块
pip install lxml
#如果下载过慢可以尝试豆瓣的链接
pip install https://pypi.douban.com/simple lxml
2.2 导入模块
from lxml import etree
2.3 使用etree
xml="""
<div>
<id>id</id>
<name>是哦</name>
<price>1.23</price>
<div class="sim-select clearfix">
<option value="xinwen" selected="selected">新闻1</option>
<option value="weibo">微博1</option>
<option value="tupian">图片1</option>
<option value="shipin">视频1</option>
<h3>
<option value="百度" selected="selected">百度1</option>
</h3>
<div class="v-line">
<option value="腾讯">腾讯1</option>
</div>
</div>
</div>
"""
tree = etree.XML(xml)
#另一种写法
tree = etree.HTML(xml)
#加载html文档(文件名为 a)
# tree = etree.parse("a.html")
# /表示层级关系,搜索子节点,第一个只有一个子节点 div
result = tree.xpath("/div")
print(result)
#想要name中的文本内容text()
result = tree.xpath("/div/name/text()")
print(result)
#想要option中的文本内容text()
result1 = tree.xpath("/div/div/option/text()")
print(result1)
#想要option中的所有的文本内容 //表示子孙后代
result2 = tree.xpath("/div/div//option/text()")
print(result2)
#想要option中的文本内容,仅想要'百度1', '腾讯'。*表示通配符
result3 = tree.xpath("/div/div/*/option/text()")
print(result3)
option_lists = tree.xpath("/div/div/option")
for option in option_lists:
#从每一个option中提取文本信息
result = option.xpath("./text()") #相对查找
print(result)
result2 = option.xpath("./@value")#获取option 中的 value 属性中的内容
print(result2)
3. xpath的语法详解
3.1 表达式
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
表达式 | 描述 | 实例 | 返回值 |
---|---|---|---|
nodename | 选取此节点的所有子节点 | bookstore | 选取 bookstore 元素的所有子节点。 |
/ | 从当前节点选取直接子节点 | bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素 |
// | 从当前节点选取子孙节点 | bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置 |
. | 选取当前节点 | ||
. . | 选取当前节点的父节点 | ||
@ | 选取属性(用于属性过滤) | //title[@lang] | 选取所有名为 lang 的属性的 title 元素 |
@ | 选取属性(用于获取属性内容) | //title/@lang | |
| | 在两个中结点中选择 | ||
() | 用()来包含| | ||
* | 包含所有元素 | //*[@class] | 选取带有class属性的所有元素 |
not | 取反 | //a[not(@class)] | 匹配没有class属性的a元素 |
3.2 XPath运算符拓展
运算符 | 描述 | 实例 | 返回值 |
---|---|---|---|
or | 或 | age=19 or age=26 | age=19:True;age=26:False |
and | 与 | age>19 and age<26 | age=19:True;age=26:False |
mod | 计算除法的余数 | 7 mod 2 | 1 |
+ | 加法 | 5 + 3 | 8 |
- | 减法 | 5 - 3 | 2 |
* | 乘法 | 5 * 3 | 15 |
div | 除法 | 8 div 4 | 2 |
= | 等于 | age=19 | |
!= | 不等于 | age!=19 | |
< | 小于 | age<19 | |
<= | 小于等于 | age<=19 | |
> | 大于 | age>19 | |
>= | 大于等于 | age>=19 |
3.3 标签顺序定位
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素,xpath的顺序是从1开始数的,[ ]表示索引 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素 |
/bookstore/book[position()< 3] | position() 当前位置;选取最前面的两个属于 bookstore 元素的子元素的 book 元素 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00 |
3.4 属性的多值匹配
text = '''
<li class="li li-first"><a href="link.html">first item</a></li>
'''
test = etree.HTML(text)
# 选取属性 class 值为 'li li-first' 的 li 元素
test.xpath('//li[@class="li li-first"]')
# 只要 class属性中 含有 值为'li' 的li 元素
# contains 包含
# 第一个参数,属性名称, 第二个参数, 属性值
test.xpath('//li[contains(@class, "li")]')
3.5 多属性匹配
当前节点有多个属性时,需要同时进行匹配
text = '''
<li class="li li-first" name='item'><a href="link.html">first item</a></li>
<li class="li la-first" name='item2'><a href="link.html">first item</a></li>
<li class="la la-first" name='item'><a href="link.html">first item</a></li>
'''
test2 = etree.HTML(text)
# 选取属性 class 含有 'la'字母 的 li 元素
test2.xpath('//li[contains(@class,"la")]')
# 选取属性 class 含有 'li'字母 的,同时属性name值为item 的 li 元素
test2.xpath('//li[contains(@class,"li") and @name="item" ]')