xpath的使用

2023年8月1日11:06:41

XPath是xml的路径语言,也是一门在xml文档中查找信息的语言。

一、xpath常用规则

表达式 描述
nodename 选取此节点的所有节点
/ 从当前节点选取子节点(从根节点开始定位)
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
text() 选取文本,/text()选取标签中直系的文本内容,//text()选取标签中所有文本内容。

(一)、举个例子

<body>
<div class="container logo-search"> 

  <div class="col search row-search-mobile">
    <form action="index.php">
      <input class="placeholder" placeholder="搜索……" name="s" autocomplete="off">
      
    </form>
  </div>

  <div class="row">
    <div class="col logo">
      <h1><a href="/">学的不仅是技术,更是梦想!</a></h1>
    </div>
        
    <div class="col search search-desktop last">
      <div class="search-input" >
      <form action="//www.runoob.com/" target="_blank">
        <input class="placeholder" id="s" name="s" placeholder="搜索……"  autocomplete="off" style="height: 44px;">
      </form>
      
      </div>
    </div>
  </div>
</div>
</body>

 以上代码树状图

1.lxml.xpath('body'):表示选取body下面的所有子节点。

2.lxml.xpath('/body'):表示从根节点开始选取body

3.lxml.xpath('body/div'):表示选取body下面含有div的所有子节点。(只能选取儿子,孙子不能选取)

4.lxml.xpath('body//div'):表示选取body下面含有div的所有节点。(只要含有div节点,儿子,孙子,重孙都可以选取)

5.lxml.xpath('//div'):选取所有body元素(不管是重孙,孙子,儿子只要含有div都可以选取,位置不限)

6.lxml.xpath('//@placeholder'):选取名为placeholder的所有属性。

二、谓语

谓语用来查找某个特定的节点或者包含某个特定值的节点,谓语用“[]”括起来。

实例

表达式 描述
/div/p[n] 选取div子元素的第n个p元素
/div/p[last()]

选取div子元素的最后一个p元素

/div/p[last()-1] 选取div子元素的倒数第二个p元素
/div/p[book<n] 选取div子元素的前n-1个book元素
//div/[@binbin] 选取所有名称为binbin的div元素
//div[@binbin='ch' 选取所有div元素,且这些元素的值为ch的binbin属性

三、通配符

通配符用来选取未知节点

通配符 描述
* 匹配任何元素的节点
@* 匹配任何属性的节点
node 匹配任何类型的节点

实例

路径表达式 结果
//div/* 选取div下的所有子元素
//div[@*] 选取带有属性的div元素

HTML属性知识补充:

属性总是以名称/值的形式出现,比如:name='binbin',属性值用双引号括起来。

属性总是在HTML元素的开始标签中规定。

HTML元素的属性

属性 描述
class classname 规定元素的类名(classname)
id id 规定元素的唯一 id
style style_definition 规定元素的行内样式
title text 规定元素的额外信息

四、属性的获取,匹配

属性的获取 属性匹配
获取a节点的href属性 路径表达式/a/@href
获取a节点的文本 路径表达式/a/[@class="thumbnail"]

获取a节点的href属性

import requests
from lxml import etree
url="http://www.kmlvyouw.com/lvyoujingdian/index.html"
headers={"User-Agent": 放自己的"}
response=requests.get(url, headers=headers) # 返回一个经过解码的字符串,response.text返回一个文本数据。
text=response.text
# text=response.content
html=etree.HTML(text) # 调用etree模块的HTML类,对response进行初始化,这样成功构造xpath解析对象。
result=html.xpath('*//div//a/@href') #  对html进行解析
for i in result:
    a=i.encode('iso-8859-1').decode('utf-8') #  服务器默认的编码是'iso-8859-1'  
    print(a)

属性多值匹配

有时候,某些节点的某个属性可能有多个值,例如:

from lxml import etree
text='''
<li class="li li-first"><a href="link.html">first item<a/></li>'''
html=etree.HTML('text')
result=html.xpath('//li[class="li li-first"]/a/text()')
print(result)

这里的html文本中li节点的class属性有两个值li和li-first,此时想用之前的属性匹配获取就无法获取,,此时的运行的结果如下:

       []

这时就需要用contains()函数了,代码可以改下如下:

from lxml import etree
text='''
<li class="li li-first"><a href="link.html">first item<a/></li>
'''
html=etree.HTML(text)
result=html.xpath('//li[contains(@class,"li-first")]/a/text()')
print(result)

通过contains方法,第一个参数传入属性名称(@属性名称),第二个参数传入属性值(属性值任意一个就可以)。运行结果如下:

['first item']

多属性匹配

如果一个属性需要多个属性来确定,那就需要匹配多个属性。此时用and来来连接就行。代码如下 

from lxml import etree
text='''
<li class="li li-first" name="item"><a href="link.html">first item</a></li>
'''
html=etree.HTML(text)
result=html.xpath('//li[contains(@class,"li-first")and @name="item"]/a/text()')
print(result)

运行结果如下:

['first item']

  • 作者:走到哪,爬到哪
  • 原文链接:https://blog.csdn.net/weixin_45827692/article/details/121417000
    更新时间:2023年8月1日11:06:41 ,共 2938 字。