数据解析之xpath
xpath解析:最常用且最便捷高效的一种解析方式,首选。
- xpath解析原理:
- 实例化一个etree对象,并将需要被解析的页面源码数据加载到该对象当中
- 调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
- 如何实例化一个etree对象:from lxml import etree
- 将本地的html文档中的源码数据加载到etree对象当中:etree.parse(filePath)
- 可以将互联网上获取的源码数据加载到该对象当中:etree.HTML('page_text')
- xpat('xpath表达式')
- xpath表达式:
- /:表示的是从根节点开始定位,表示一个层级
- //:表示多个层级,可以从任意位置开始定位
- 属性定位://div[@class="song"],格式为://tagName[@attrName="attrValue"]
- 索引定位://div[@class="song"]/p[3],格式为://tagName[@attrName="attrValue"]/tagName[索引值],注:索引是从1开始的
- 取文本:/text():获取标签中直系的文本内容;//text():获取标签中非直系的文本内容
- 取属性:/@attrName,格式为://tagName[@attrName="attrValue"]/@attrName
接下来通过几个项目案例来练习:
案例一:爬取4k高清图片并保存
首先需要分析页面源码数据,可知每张图片保存在属性值为slist的<div>标签中的每个<li>标签中,利用xpath进行数据解析的话,首先通过:li_list = tree.xpath('//div[@class="slist"]//li') 来获取<li>标签的一个了列表,然后对该列表进行遍历,对于每个<li>再进行图片src与alt属性的获取,获取方式分别为:li.xpath('./a/img/@src')[0]与li.xpath('./a/img/@alt')[0],最后模拟请求图片的URL,拼接图片名称与存储路径,进行持久化存储即可。
其中遇到了乱码的问题,解决方法有两种:
(一)在对整张页面数据进行获取时,就进行编码的设置:
response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text
(二)在对图片名称进行获取时,进行编码设置:
img_name = name.encode('iso-8859-1').decode('gbk')
# @Time : 2022/1/18 0018 10:22 # @Author : Tzy0425 # @File : xpath爬取案例2.py # 解析下载图片数据 import requests import os from lxml import etree if __name__ == '__main__': headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36' } if not os.path.exists('./4kpic'): os.mkdir('./4kpic') url = 'https://pic.netbian.com/4kyouxi/' page_text = requests.get(url=url,headers=headers).text tree = etree.HTML(page_text) li_list = tree.xpath('//div[@class="slist"]//li') for li in li_list: src = 'https://pic.netbian.com/' + li.xpath('./a/img/@src')[0] name = li.xpath('./a/img/@alt')[0] + '.jpg' # 图片名称出现乱码问题,通用解决方法 img_name = name.encode('iso-8859-1').decode('gbk') img_data = requests.get(url=src,headers=headers).content img_path = '4kpic/' + img_name with open(img_path,'wb') as fp: fp.write(img_data) print(img_name,'下载成功!!!')