最近学习了xpath相关的知识,以下是学习过程中记录的笔记
一、简介
1、xpath属于xml/html解析数据的一种方式, 基于元素(Element)的树形结构(Node > Element)。选择某一元素时,根据元素的路径选择,如 /html/head/title获取<title>标签。
2、安装&使用
使用lxml解析
安装:pip install lxml
导入库:from lxml import etree
lxml将html文本转成xml对象:tree = etree.HTML(html)
其中:
Xpath中text(),string(),data()的区别如下:
text()仅仅返回所指元素的文本内容。
string()函数会得到所指元素的所有节点文本内容,这些文本讲会被拼接成一个字符串。
data()大多数时候,data()函数和string()函数通用,而且不建议经常使用data()函数,有数据表明,该函数会影响XPath的性能。
二、常用规则
表达式 | 功能 |
nodename | 选取此节点的所有子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取直接子孙节点 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
三、查找
1、路径写法
/ | 依次查找 |
// | 间接查找 |
./ | 从当前元素下查找 |
.// | 从当前元素下的子节点查找 |
2、位置条件
//li[1] | 整个文档中的第一个<li>标签 |
//li[last()] | 最后一个 |
//li[position() < 3] | 前2个 |
//li[position() -2] | 倒数第二个 |
3、属性条件
//li[@id="xxx"] | id属性查找 |
//li[@class="xxx"] | class属性查找 |
//li[@class="xxx" and @name="xxx"] | 多属性的且查找 |
4、模糊条件
//div[constains(@class,"page")] | 查找class属性包含page的所有div标签 |
//div[starts-with(@class,"box")] | 第一个class的属性值为box的div标签 |
//div[ends-with(@class,"clearfix")] | 最一个class的属性值为clearfix的div标签 |
四、数据提取
1、提取文本
例如://title/text()
2、提取属性
例如://img/@href
3、同时提取2个属性
//title/text() | //img/@src
五、示例
爬取csdn网站Python板块的列表信息
import requests
from lxml import etree
resp = requests.get(url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'})
if resp.status_code == 200:
html = resp.text
# print(resp.text)
root = etree.HTML(html)
divs = root.xpath('//ul[@id="feedlist_id"]//div[@class="list_con"]')
print(divs)
for div in divs:
# print(div)
item = {}
item['title'] = div.xpath('.//div[@class="title"]/h2/a/text()')[0]
item['title'] = item['title'].strip() # strip() 去除2端的空白字符
item['author'] = div.xpath('./dl[@class="list_userbar"]/dd[@class="name"]/a/text()')[0]
item['author'] = item['author'].strip()
print(item)
六、其他
(1) 选取所有节点
a = html.xpath('//*') # 选取所有的节点
b = html.xpath('//a') # 选取所有的a节点,是一个例子
(2) 选取子节点
c = html.xpath('//li/a') # 选取li节点的直接a子节点
d = html.xpath('//li//a') # 选取li节点的所有a子节点
(3) 选取父节点
e = html.xpath('//li/../a') # 选取li节点的父节点下的a节点
f = html.xpath('//li/parent::/a') # 选取li节点的父节点下的直接a节点
g = html.xpath('//li/parent::*/a') # 选取li节点的父节点下的所有a节点