一、jsonpath
1.安装
pip install jsonpath
2.使用
只能解析本地文件
.json文件
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
.py文件
# _*_ coding : utf-8 _*_
# @Time : 2025/2/19 12:34
# @Author : 20250206-里奥
# @File : demo09_jsonpath_淘票票
# @Project : PythonPro17-21
#导入
import json
import jsonpath
#到文件
obj = json.load(open('test.json','r',encoding = 'utf-8'))
print(obj)
#书店所有书的作者
author_list = jsonpath.jsonpath(obj,'$.store.book[*].author')
print(author_list)
#所有的作者
author_list1 = jsonpath.jsonpath(obj,'$..author')
print(author_list1)
#store下的所有元素
tag_list = jsonpath.jsonpath(obj,'$.store.*')
print(tag_list)
# store里面所有东西的价格
price_list = jsonpath.jsonpath(obj,'$.store..price')
print(price_list)
#第3本书
book_third = jsonpath.jsonpath(obj,'$..book[2]')
print(book_third)
# 最后一本书
book_last = jsonpath.jsonpath(obj,'$..book[(@.length - 1)]')
print(book_last)
# 前2本书
book_firstAndSecond = jsonpath.jsonpath(obj,'$..book[0,1]')
print(book_firstAndSecond)
print("\n")
book_firstAndSecondNew = jsonpath.jsonpath(obj,"$..book[:2]")
print(book_firstAndSecondNew)
# 过滤出所有包含isbn的书
# 条件过滤: 需要在()前加?
book_list3 = jsonpath.jsonpath(obj,"$..book[?(@.isbn)]")
print(book_list3)
#超过十块钱的书
book_list4 = jsonpath.jsonpath(obj,"$..book[?(@.price > 10)]")
print(book_list4)
# CTRL + alt + L ————》排版生成的.json文件
xpath和jsonpath对比:
jsonpath解析淘票票-城市地址
# _*_ coding : utf-8 _*_
# @Time : 2025/2/19 13:26
# @Author : 20250206-里奥
# @File : demo08_jsonpath_解析淘票票
# @Project : PythonPro17-21
import urllib.request
url = 'https://dianying.taobao.com/cityAction.json?activityId&_ksTS=1739942948773_108&jsoncallback=jsonp109&action=cityAction&n_s=new&event_submit_doGetAllRegion=true'
headers = {
#请求头中,以“:”符号开头的注释掉。
# ':authority':'dianying.taobao.com',
# ':method':'GET',
# ':path':'/cityAction.json?activityId&_ksTS=1739942948773_108&jsoncallback=jsonp109&action=cityAction&n_s=new&event_submit_doGetAllRegion=true',
# ':scheme':'https',
'accept':'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01',
#默认不支持utf-8的编码格式。 'gzip, deflate, br, zstd'
# 'accept-encoding':'gzip, deflate, br, zstd',
'accept-language':'zh-CN,zh;q=0.9',
'bx-v':'2.5.28',
'cookie':'t=3f22f9c912700c231e2e9e22079d2cec; cookie2=19434e4c86fbda6d54c07ee336bc2027; v=0; _tb_token_=763b7139648b9; cna=CVo8IB2qjWwCAW8CsA6MaAcB; xlly_s=1; isg=BFdXeyfL_BuZhHiX9b7tGjF05suhnCv-ej4MFKmE9SaN2HYasWwNT3T2OnhGMAN2',
'priority':'u=1, i',
'referer':'https://dianying.taobao.com/',
'sec-ch-ua':'"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
'sec-ch-ua-mobile':'?0',
'sec-ch-ua-platform':'"Windows"',
'sec-fetch-dest':'empty',
'sec-fetch-mode':'cors',
'sec-fetch-site':'same-origin',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
'x-requested-with':'XMLHttpRequest',
}
#请求对象定制
request = urllib.request.Request(url = url,headers=headers)
#模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
#返回响应内容
content = response.read().decode('utf-8')
# 解决jsonpath.用split切割
#[1]表示取第2个元素——》被切割的左边第一个位置的元素没了
#[0]表示取第1个元素————》被切割的右边元素没了
#split( '(' )、split( ')' )分别表示:切割“(”符号左边的数据,和切割“)”符号右边的数据
content = content.split('(')[1].split(')')[0]
#打印
print(content)
with open('淘票票.json','w',encoding='utf-8') as fp:
fp.write(content)
# 只要生成文件里的"regionName": "阿拉尔"...,其余的不要
import json
import jsonpath
# 加载文件
obj = json.load(open('淘票票.json','r',encoding='utf-8'))
city_list = jsonpath.jsonpath(obj,'$..regionName')
print(city_list)
#在线
#json.cn--->json在线解析---》赋值打印的运行结果--->
# 粘贴到json在线解析---》删除“jsonxx(” 以及结束的 “)...” 原因:他们不是json字符串中的内容
# ---》
二、BeautifulSopu
简称bs4
功能
解析和提取数据
缺点:
没有lxml效率高
优点:
接口人性化,使用方便
1. 安装
pip install bs4
2. 使用
解析本地文件
解析服务器响应文件
.HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<ul>
<li id="l1">zs</li>
<li id="l2">ls</li>
<li>ww</li>
<a href="" id="" class="a1">25219</a>
<span>hhhaa</span>
</ul>
</div>
<ul>
<li>吃</li>
<li>喝</li>
<l>睡</l>
</ul>
<a href="" title="a2">百度</a>
<div id="d1">
<span>hhhee</span>
</div>
<p id="p1" class="p1">wawww</p>
</body>
</html>
.py文件
# _*_ coding : utf-8 _*_
# @Time : 2025/2/19 16:05
# @Author : 20250206-里奥
# @File : demo10_bs4的基本使用
# @Project : PythonPro17-21
#导入
from bs4 import BeautifulSoup
# 通过解析本地文件学习bs4的基础语法
# 加载本地文件
# 默认打开的文件,的编码格式是gbk,需要指定编码格式
soup = BeautifulSoup(open('bs4的基本使用.html',encoding='utf-8'),'lxml')
print(soup)
#根据标签名查找节点
#找到的是第一个符合条件的数据
print(soup.a)
#获取标签的属性和属性值
print(soup.a.attrs)
#bs4的一些函数
#1)find()
#2)find_all()
#3)select()
# find()
# 返回第一个符号条件的数据
print(soup.find('a'))
# 根据title的值找到对应的标签对象
print(soup.find('a',title = "a2"))
# 根据class的值找到对应的标签对象
#class是关键字,不能使用。可以加个_————》class_,表示既能代表class,又不是class
print(soup.find('a',class_ = 'a1'))
#find_all()
# 返回所有a标签组成的列表
print(soup.find_all('a'))
#如果想获取多个标签数据,那么在find_all的参数中需要添加列表数据
print(soup.find_all(['a','span']))
#获取所有li标签
print(soup.find_all('li'))
# 获取部分li标签.limit的作用:查找前几个li标签
print(soup.find_all('li',limit=2))
#select【推荐】,5个用法
#通过标签获取节点对象,返回的是多个数据的一个列表
print(soup.select('a'))
#类选择器。可以通过”.“符号代表class
print(soup.select('.a1'))
#id.
print(soup.select('#l1'))
# 属性选择器,获取具有id属性的li标签
print(soup.select('li[id]'))
# 查找id为l2的li标签
print(soup.select('li[id = "l2"]'))
# 层级选择器[3个:1:空格;2.大于号>;3.逗号,]
#后代选择器。获取div标签下的li标签 [空格]
print(soup.select('div li'))
#子代选择器 [大于号> ]
# 很多计算机编程语言中,如果不加空格————》不会输出内容,但是在bs4中会显示内容,不会报错
print(soup.select('div > ul > li'))
# 组合。 【逗号,】
# 找到a标签和li标签所有对象
print(soup.select('a,li'))
# 4)节点信息
#获取节点内容. select返回值是一个列表,可以通过下标获取列表中内容
obj = soup.select('#d1')[0]
# 如果标签对象中只有内容,string和get_text()都可以使用
#如果标签对象中不仅有内容,还有标签。那么string获取不到内容,get_text()能获取内容
#推荐使用get_text()
print(obj.string)
print(obj.get_text())
#节点属性
#select返回值是一个列表,没有name属性。通过下标访问
obj = soup.select('#p1')[0]
# name是标签名
print(obj.name)
#将属性值作为一个字典返回
print(obj.attrs)
# 获取节点属性
obj = soup.select('#p1')[0]
# 以下3种获取方式
print(obj.attrs.get('class'))
print(obj.get('class'))
print(obj['class'])