xpath解析

XPath 使用路径表达式来选取HTML/ XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

使用xpath解析要先安装lxml模块。 pip install lxml

1.选取节点

表达式描述
nodename 选取此节点的所有子节点。
/ 从根节点选取(取子节点)。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置(取子孙节点)。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

2.路径表达式

路径表达式含义
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

3.谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

路径表达式结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。

4.选取未知节点

通配符描述和示例
* 匹配任何元素节点。/bookstore/*   选取 bookstore 元素的所有子元素。 
@* 匹配任何属性节点。//*  选取结果中的所有元素。
node() 匹配任何类型的节点。//title[@*]  选取所有带有属性的 title 元素。

5.选取部分节点

路径表达式结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

6.示例:

假设有请求获得如下返回信息 html_data

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <div id="header" class="">
 9     <div class="header clearfix">
10         <a class="logo left" href="/"><img src="https://xx" alt=""></a>
11         <ul class="xx">
12             <li><a href="http://www.xx.com">首页</a></li>
13         </ul>
14     </div>
15 </div>
16 <div class="wrap">
17     <ul class="c-list">
18         <li class="cdata">
19             <div class="c-info">
20                 <a class="cname" href="" target="_blank">第一条</a>
21                 <p class="major">张三</p>
22                 <div class="score">
23                     <span class="bb"></span>
24                     <span>59分</span>
25                 </div>
26             </div>
27         </li>
28         
29         <li class="cdata">
30             <div class="c-info">
31                 <a class="cname" href="" target="_blank">第二条</a>
32                 <p class="major">李四</p>
33                 <div class="score">
34                     <span class="bb"></span>
35                     <span>67分</span>
36                 </div>
37             </div>
38         </li>
39         
40         <li class="cdata">
41             <div class="c-info">
42                 <a class="cname" href="" target="_blank">第三条</a>
43                 <p class="major">王五</p>
44                 <div class="score">
45                     <span class="bb"></span>
46                     <span>88分</span>
47                 </div>
48             </div>
49         </li>
50     </ul>
51 </div>
52 </body>
53 </html>
View Code
from lxml import etree

html = etree.HTML(html_data)
all_list = html.xpath('//body')
print(all_list)
data_list = html.xpath('//li[@class="cdata"]')  # 获取属性class="cdata"的所有li元素
print(data_list)
for li in data_list:
    # 获取li元素下的 div元素下的 a标签的 文本值 ,xpath方法返回的是列表数据,此处只有一个元素,用索引0获取;即"第一条","第二条","第三条"
    cname = li.xpath('./div/a/text()')[0]
# 获取属性 class="wrap" 的div元素
div_wrap = all_list[0].xpath('//div[@class="wrap"]')
# 获取div下的 ul下的 第3个li下的 div下的 div下的 第1个span的 属性class的值, 即bb
bb_wangwu = div_wrap[0].xpath('./ul/li[3]/div/div/span[1]/@class')[0]

 

posted on 2023-04-11 17:13  木去  阅读(103)  评论(0)    收藏  举报