一、 XPath 表达式概述
什么是 XPath?
- XPath 是一种用于在 XML 或 HTML 文档中定位元素的语言。
- XPath 使用路径表达式来选取节点或节点集。
- 在 Python 中,可以使用XPath来解析 XML 或 HTML 文档,并提取所需的数据。
XPath 语法
- XPath 语法由不同的表达式组成,用于选择节点或节点集。
- 以下是一些常用的 XPath 表达式:
-
nodename
:选择指定节点名称的所有节点。
-
/
:从根节点开始选择。
-
//
:选择匹配选择的任何位置的节点。
-
.
:选择当前节点。
-
..
:选择当前节点的父节点。
-
@
:选择属性。
二、 在 Python 中使用 XPath
使用 lxml 库
- 在 Python 中,可以使用第三方库 lxml 来解析 XML 或 HTML 文档,并使用 XPath 来选择节点。
- 首先,需要安装 lxml 库:
pip install lxml
解析 HTML 文档
from lxml import etree
# 解析 HTML 文档
# 创建解析器
parse = etree.HTMLParser(encoding='utf-8')
# 把test.html文件加载到对象中,并且指定解析器
tree = etree.parse('test.html',parser=parse)
# 通过 xpath 语法去定位某个标签
print(tree.xpath('/html/head/link')) # 最左边的/:从根标签开始定位指定的标签
# 中间的/:代表一个层级
# print(tree.xpath('/link')) # 最左边的/:从根标签开始定位指定的标签
print(tree.xpath('/html//link')) # // 从当前节点获取子孙link节点
print(tree.xpath('/html')) # 获取html节点
print(tree.xpath('//div')) # 所有div节点
# 加属性匹配 [@属性名="属性值"]
print(tree.xpath('//div[@class="footer-box"]'))
# 在xpath中 找第几个 不是从0开始 要找第几个,就写几
print(tree.xpath('//div[@class="footer-box"]/div/p[1]'))
# <a href="http://www.taobao.com" id=1>淘宝</a>
print(tree.xpath('//div[@class="footer-box"]/div/p[1]/a[1]/text()'))
# 获取标签内的文本内容
print(tree.xpath('//div[@class="footer-box"]/div/p[1]/a/text()'))
# 获取id为1 的a标签中的内容
print(tree.xpath('//a[@id="1"]/text()'))
print(tree.xpath('//div[@class="footer-content"]/p[1]/a//text()'))
# /text() : 直系文本内容
# //text() :所有文本内容
# 获取标签属性值
# /@属性名
print(tree.xpath('//a[@class="product"]/@href'))
print(tree.xpath('//p[@class="copyright-desc"]//text()'))
ls = tree.xpath('//p[@class="copyright-desc"]//text()')
print(ls)
# 列表如何转为字符串?再对字符串内容进行替换
print(' '.join(ls).replace('\r\n ',''))
# print(tree.xpath('./'))
p = tree.xpath('//p[@class="top-content"]')
print(p)
# 因为xpath返回的类型是列表类型,需要从列表类型中获取元素对象.xpath('./a') 从当前p标签中获取子节点
print(p[0].xpath('./a'))
# 获取当前 p标签的父节点
print(p[0].xpath('..'))
XPath 表达式示例
- 以下是一些 XPath 表达式的示例:
-
//p
:选择所有 p节点。
-
//p[@class="top-content"]
:选择 class 属性为 top-content 的 p节点。
-
//p/a[1]/text()
:选择所有 p节点下的第一个 a节点的文本内容。
-
//p/a//text()
:选择所有 p节点下的所有 a节点的文本内容(包含 a 下的子孙节点的文本内容)。
安居客案例
'''
1-明确目标
2-发起请求
3-获取响应数据
4-提取数据
'''
import requests
from lxml import etree
url = 'https://cs.zu.anjuke.com/?from=HomePage_TopBar'
res = requests.get(url)
# //h3/a/b[@class="strongbox"]/text()
# 把响应中的数据交给 lxml 进行解析,获取 etree 对象
tree = etree.HTML(res.text)
# print(tree.xpath('//h3/a/b[@class="strongbox"]/text()'))
# print(tree.xpath('//strong/b[@class="strongbox"]/text()'))
div = tree.xpath('//div[@class="zu-itemmod"]')
# 包含了标题,价格,地址,详情
# print(len(div))
for i in div: # 每循环一次,获取到的是一个 div 对象、
# 从该 div 对象中获取到具体标题.价格....
title = i.xpath('./div/h3/a/b/text()')[0] # 因为 xpath 返回的是一个列表,列表中只有一个标题数据,所以列表的索引取值
price = i.xpath('.//div[@class="zu-side"]//b/text()')[0] # 因为 xpath 返回的是一个列表,列表中只有一个价格数据,所以列表的索引取值
address = i.xpath('.//address[@class="details-item"]//text()')
address = ''.join(address).replace('\n','').replace(' ','')
# print(title,price,address)
# 保存到文本中
with open('租房.txt','a',encoding='utf-8')as f:
# 写入数据到文件中
f.write(title + ',' + price + ','+ address + '\n')
总结
- Python 中的 XPath 表达式可以用于解析 XML 或 HTML 文档,并选择所需的节点。
- 使用 lxml 库可以方便地解析文档并使用 XPath 来选择节点。
- XPath 的语法灵活且强大,可以根据需要选择不同的节点。