数据解析之xpath
一、环境安装
下载lxml
pip install lxml
二、使用
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
常用xpath表达式:
属性定位: #找到class属性值为song的div标签 //div[@class="song"] 层级&索引定位: #找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a //div[@class="tang"]/ul/li[2]/a
# 根据标签内容text来定位
//div[@class='outside']//a[contains(text(),'最近浏览')
逻辑运算: #找到href属性值为空且class属性值为du的a标签 //a[@href="" and @class="du"] 模糊匹配: //div[contains(@class, "ng")] //div[starts-with(@class, "ta")]
//a[contains(text(),'最近浏览')
取文本: # /表示获取某个标签下的文本内容 # //表示获取某个标签下的文本内容和所有子标签下的文本内容 //div[@class="song"]/p[1]/text() //div[@class="tang"]//text() 取属性: //div[@class="tang"]//li[2]/a/@href
xpath解析原理(编码流程):
- - 实例化一个etree的对象,且将页面源码数据加载到该对象中
- - 调用etree对象中的xpath方法实现标签定位和数据的提取
- - 在xpath函数中必须作用xpath表达式
可以给浏览器安一个xpath插件--xpath.crx
- 安装方式,打开浏览器开发者模式,直接将xpath.crx 拖进去
- xpath插件的开启和关闭的快捷键:
- ctrl+shift+x
- 可进行xpath表达式的校验
xpath解析案例
- 一、爬取煎蛋网图片数据http://jandan.net/ooxx
- 图片src是加密的,加密方式封装在标签调用的函数中
- 先爬取密文,然后根据加密方式解密。
# 需求,爬取煎蛋网图片数据, 图片的src加密了 import requests from lxml import etree import base64 # 对src加密的方法 from urllib import request headers ={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.12 Safari/537.36' } url = "http://jandan.net/ooxx/page-64#comments" page_text = requests.get(url,headers=headers).text # 解析图片src密文 tree = etree.HTML(page_text) code_list = tree.xpath('//span[@class="img-hash"]/text()') # 获取密文 # 解析密文 for code in code_list: img_url = "http:" + base64.b64decode(code).decode() imgName = img_url.split('/')[-1] request.urlretrieve(img_url, imgName) print(imgName,"下载成功")
二、站长素材简历模板爬取
- 报这个错::连接池的错误,高频访问占用连接对象。
- HTTPConnectionPool(host:XX)Max retries exceeded with url:
- 解决办法:
- 1. 请求头中设置 'Connection':'close'
- 如何让请求结束后马上断开连接且释放池中的连接资源: 'Connection':'close' # 请求成功之后马上断开连接
- 2. 或使用代理ip
- 1. 请求头中设置 'Connection':'close'
import requests from lxml import etree import random import os headers ={ 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.12 Safari/537.36', 'Connection':'close' # 请求成功之后马上断开连接 } url_one = "http://sc.chinaz.com/jianli/free.html" # 定制一个通用url摸版 url_demo = "http://sc.chinaz.com/jianli/free_%d.html" start_page = int(input("开始页")) end_page = int(input("结束页")) for pageNum in range(start_page,end_page+1): if pageNum == 1: url = url_one else: url = format(url_demo%pageNum) response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' # 编码 page_text = response.text # 解析简历详情页的url html = etree.HTML(page_text) div_list = html.xpath('//div[@id="container"]/div') for div in div_list: name = div.xpath('./p/a/text()')[0] url_detail = div.xpath('./p/a/@href')[0] #对详情页的url发起请求,获取详情页的源码数据 detail_page_text = requests.get(url_detail,headers=headers).text tree = etree.HTML(detail_page_text) li_list = tree.xpath('//div[@class="clearfix mt20 downlist"]/ul/li') #随机选取一个li标签(li标签中包含了下载地址的url) download_url = random.choice(li_list).xpath('./a/@href')[0] #进行简历数据的下载 data = requests.get(url=download_url,headers=headers).content name = name+'.rar' # 压缩包 if not os.path.exists("./简历模板"): os.mkdir("./简历模板") with open(f"./简历模板/{name}", 'wb') as fp: fp.write(data) print(name,"下载成功")
根据标签内容text来定位