一、XPath是什么?
在 Python 里,XPath(XML Path Language)是一种用于在 XML 或 HTML 文档中定位节点的语言,常被用于解析和提取网页数据。Python 中有多个库可以使用 XPath 来处理 XML 和 HTML 文档,下面主要介绍 lxml 库以及 BeautifulSoup 结合 lxml 解析器的使用方法。
二、xpath节点
以html为例,每个标签我们称之为【节点】,同理xml亦是。

其中红框的是节点,其中标签是【根节点】
三、语法规则
| 表达式 | 描述 |
|---|---|
| / | 选中该元素 |
| // | 从根节点选取、或者是元素和元素间的过渡 |
| · | 选取当前节点 |
| ·· | 选取当前节点的父节点 |
| @ | 选取属性 |
| text() | 选取文本 |
三、安装
安装清华源的lxml
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
安装成功后
from lxml import etree
html = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<div>
<ul>
<li>1<h1>蜘蛛侠</h1></li>
<li>2<h1>蝙蝠侠</h1></li>
<li>3<h2>钢铁侠</h2></li>
<li class ="lol">4<p>盖伦</p></li>
<li>5<p>绿巨人</p></li>
</ul>
</div>
<div>
<ul>
<li><a><p>超人钢铁之躯</p></a></li>
<li class ="lol"><a><p>德莱文</p></a></li>
<li class ="Marvel"><a><p>雷神</p></a></li>
<li class ="DC"><a><p>神奇女侠</p></a></li>
<li><a><h1>美国队长</h1></a></li>
<li><a><h3>葫芦娃</h3></a></li>
</ul>
</div>
</div>
</body>
</html>
'''
html_obj = etree.HTML(html) #解析html内容,返回一个Element对象
print(type(html_obj)) #<class 'lxml.etree._Element'> 返回的是Element对象
h1_list = html_obj.xpath('//h1')
h1_list_text = html_obj.xpath('//h1/text()')
for element,text in zip(h1_list,h1_list_text):
item = dict()
item['element']= element
item['text']= text
print(item)
#{'element': <Element h1 at 0x1d3ec0d7f80>, 'text': '蜘蛛侠'}
#{'element': <Element h1 at 0x1d3ec0d7fc0>, 'text': '蝙蝠侠'}
#{'element': <Element h1 at 0x1d3ec0e0040>, 'text': '美国队长'}
// 从根节点选取到目的标签的过渡
h1_list = html_obj.xpath("//h1") #获取所有h1对象,返回的是列表
print(h1_list) #[<Element h1 at 0x1d3ec0d7f80>, <Element h1 at 0x1d3ec0d7fc0>, <Element h1 at 0x1d3ec0e0040>]
# "//li" 则可以获取所有li对象
text() 获取文本内容
h1_list_text = html_obj.xpath("//h1/text()") #获取h1所有对象的文本,返回的是列表
print(h1_list_text) #['蜘蛛侠', '蝙蝠侠', '美国队长']
#"//p/text()" 则可以获取所有li对象的文本
@选择属性
li_obj_lol = html_obj.xpath('//li[@class="lol"]') #选择class属性为lol的节点
print(li_obj_lol) #[<Element li at 0x16c605f02c0>, <Element li at 0x16c605f0300>]
以这个为例<html lang="en">
lang = html_obj.xpath("//html[@lang='en']") #[<Element html at 0x217bed81c00>]
查询特定节点
str='''
<div class="container">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<div>
'''
html_obj = etree.HTML(str)
#用[]表示第N个
li_text = html_obj.xpath("//div[@class='container']/ul/li[2]/text()") #选择ul中的第二个li文本
print(li_text) # ['2']
这里需要注意的是,只能选择li的文本并不是选择li里的节点的文本
last()
li_text = html_obj.xpath("//div[@class='container']/ul/li[last()]/text()") #选择ul中的最后一个li文本
print(li_text) # ['6']
li_text = html_obj.xpath("//div[@class='container']/ul/li[last()-1]/text()") #选择ul中的最后一个li文本
print(li_text) # ['5']
position()
#搜索从第二个li开始的li
li_text = html_obj.xpath("//div[@class='container']/ul/li[position()>1]/text()")
print(li_text) # ['2', '3', '4', '5', '6']
#搜索大于1小于的li文本
li_text = html_obj.xpath("//div[@class='container']/ul/li[position()>1 and position()< 6]/text()")
print(li_text) # ['2', '3', '4', '5', '6']
以上是基础使用方法。
PS:若有错误或遗漏,请评论说明,谢谢。


被折叠的 条评论
为什么被折叠?



