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>
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]
浙公网安备 33010602011771号