当前位置: 首页 > news >正文

Python爬虫基础与应用

目录

爬虫介绍

什么是爬虫?

爬虫有什么作用?

爬虫应用领域

业界的情况如何

爬虫的合法性

合法的爬虫

不合法的爬虫

反爬与反反爬

爬虫的基本套路

选择一门语言

浏览器- 开发者工具

爬虫靶场

访问方式

第一个爬虫

数据来源

小试牛刀

requests模块-请求方式

文档地址

安装

基本请求

获取响应信息

requests模块-请求方式

Form表单

Json参数

爬虫cookie的保存与使用

代码

爬虫Token的使用

Token的使用场景

代码

数据的格式

Python使用正则

常用方法

正则表达式实战

数据解析-Beautiful Soup的使用

简介

Beautiful Soup 安装

创建 Beautiful Soup 对象

三大对象种类

Tag

获取属性

Comment

数据解析-Beautiful Soup方法的使用

find_all() 搜索文档树

字符串

正则表达式

列表

keyword

True

按CSS搜索

按属性的搜索

CSS选择器

BS4实战

数据解析-xpath的使用

介绍

XPath语法

节点的关系

常用的路径表达式

通配符

选取若干路径

谓语

运算符

选择XML文件中节点:

XPath工具

安装

JSON数据使用

Python中的json模块

json.loads()

json.dumps()

json.dump()

json.load()

注意事项

JsonPath的使用

安装

JsonPath与XPath语法对比

代码


爬虫介绍

img

什么是爬虫?

网络爬虫也叫网络蜘蛛,如果把互联网比喻成一个蜘蛛网,那么蜘蛛就是在网上爬来爬去 的蜘蛛,爬虫程序通过请求url地址,根据响应的内容进行解析采集数据

image-20210521191536426

简单的说:就是用代码模拟人的行为,去各各网站溜达、点点按钮、查查数据。或者把看到的数据拿下来。

爬虫有什么作用?

通过有效的爬虫手段批量采集数据,可以降低人工成本,提高有效数据量,给予运营/销售的数据支撑,加快产品发展。

image

image-20220525090946830

image-20210521191932776

爬虫应用领域

  • 批量采集某个领域的招聘数据,对某个行业的招聘情况进行分析
  • 批量采集某个行业的电商数据,以分析出具体热销商品,进行商业决策 • 采集目标客户数据,以进行后续营销
  • 批量爬取腾讯动漫的漫画,以实现脱网本地集中浏览
  • 开发一款火车票抢票程序,以实现自动抢票
  • 爬取评论,舆情监控
  • 爬取说说信息,分析上线时间
  • ...

业界的情况如何

目前互联网产品竞争激烈,业界大部分都会使用爬虫技术对竞品产品的数据进行挖掘、采集、大数据分析,这是必备手段,并且部分公司都设立了爬虫工程师的岗位

爬虫的合法性

image-20220515171104421

民间流传出下面一段话:

爬虫爬得欢,监狱要坐穿; 数据玩的溜,牢饭吃个够

image-20210521183941756

问题

爬虫是否是合法的呢?

答案

有时合法,有时不合法,因情况而定

爬虫是利用程序进行批量爬取网上的公开信息,也就是前端显示的数据信息。因为信息是完全公开的,所以是常规合法的!!!

合法的爬虫
  • 公开的数据,没有标识不可爬取
  • 不影响别人服务器
  • 不影响的业务
不合法的爬虫
  • 用户数据

  • 部分网站、APP数据超过指定数量

  • 明文规定不让爬取

    • 在域名后加上/robots.txt查看
    • 页面上标明
  • 影响业务

  • 影响服务器

    类似DDOS攻击的问题

提示

部分爬虫虽然违法,但公司、或企业不会直接报警。会采用反爬的手段,严重后才会报警

反爬与反反爬

image-20220525135540668

反爬:有时企业不想自己的数据被别人拿到。这时就会设置反爬的手段,来不让爬虫获取数据。

反爬虫常用一些手段:

  • 合法检测:请求校验(useragent,referer,接口加签 ,等)
  • 验证码:识别文字、做题、滑动等
  • 小黑屋:IP/用户限制请求频率,或者直接拦截
  • 投毒:反爬虫高境界可以不用拦截,拦截是一时的,投毒返回虚假数据,可以误导竞品决策
  • ... ...

反反爬:破解掉反爬手段,再获取其数据。所有的手段都能破解吗?

道高一尺魔高一丈,这是一场没有硝烟的战争,程序员VS程序员

爬虫的基本套路

image-20220515175555751

  • 基本流程

    • 目标数据:想要什么数据

    • 来源地址

    • 结构分析

      • 具体数据在哪(网站、还是APP)
      • 如何展示的数据
    • 实现构思

    • 操刀编码

  • 基本手段

    • 破解请求限制

      • 请求头设置,如:useragant为有效客户端
      • 控制请求频率(根据实际情景)
      • IP代理
      • 签名/加密参数从html/cookie/js分析
    • 破解登录授权

      • 请求带上用户cookie信息
    • 破解验证码

      • 简单的验证码可以使用识图读验证码第三方库
  • 解析数据

    • HTML Dom解析

      • 正则匹配,通过的正则表达式来匹配想要爬取的数据,如:有些数据不是在html 标签里,而是在html的script 标签的js变量中
      • 使用第三方库解析html dom,比较喜欢类jquery的库
    • 数据字符串

      • 正则匹配(根据情景使用)
      • 转 JSON/XML 对象进行解析

选择一门语言

爬虫可以用各种语言写, C++, Java都可以, 为什么要Python?

  • 简单
  • 高效
  • 三方模块库多

浏览器- 开发者工具

image-20220527161640583

对于爬虫来说,最核心的就是发送请求,让网络服务器返回相应的数据。而最为核心之一就是找到URL,这时就需要一个可以帮助我们分析URL的工具,浏览器开发者工具

image-20220527162316999

image-20220527164154213

image-20220527164454745

爬虫靶场

爬虫靶场的主要作用:

  1. 学习和练习

    • 为开发者提供一个安全的环境来练习网页爬虫技术
    • 可以测试不同的爬虫策略和技术,而不用担心影响真实网站
    • 适合新手学习基础爬虫概念和技术
  2. 测试和调试

    • 可以测试爬虫程序在各种场景下的表现
    • 帮助开发者发现和解决爬虫代码中的问题
    • 验证爬虫的稳定性和可靠性

通过使用爬虫靶场,开发者可以:

  • 在安全的环境中提升爬虫开发技能
  • 为实际项目积累经验和最佳实践

访问方式

  • 直接访问

    http://58.87.96.193:8000/

  • docker 部署,具体步骤如下:

# 下载docker镜像
docker pull registry.cn-hangzhou.aliyuncs.com/bz_python/scrapy_center:0.1
# 创建容器,启动爬虫靶场
docker run -d -p 8000:8000 -p 3306:3306 --name scrapecenter 0bd5

第一个爬虫

image-20220515180821632

数据来源

  • 网站
  • 移动端

小试牛刀

怎样扒网页呢?

其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS、CSS。如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML

  • HTML 70%
  • JS 20%
  • CSS 10%

image-20220518140335975

爬取页面,代码如下:

from urllib.request import urlopenresponse = urlopen("http://www.baidu.com/")
print(response.read().decode())

注意

urllib模块库是python自带的。在Python2叫urllib2

真正的程序就两行,执行如下命令查看运行结果,感受一下

看,这个网页的源码已经被我们扒下来了,是不是很酸爽?

requests模块-请求方式

image-20220518125003228

文档地址

https://requests.readthedocs.io/

安装

利用 pip 安装

pip install requests==2.32.3

基本请求

req = requests.get("http://www.baidu.com")
req = requests.post("http://www.baidu.com")
req = requests.put("http://www.baidu.com")
req = requests.delete("http://www.baidu.com")
req = requests.head("http://www.baidu.com")
req = requests.options("http://www.baidu.com")

获取响应信息

代码含义
resp.json()获取响应内容(以json字符串)
resp.text获取响应内容 (以字符串)
resp.content获取响应内容(以字节的方式)
resp.encoding获取网页编码
resp.headers获取响应头内容
resp.request.headers请求头内容
resp.url获取访问地址
resp.cookie获取cookie

requests模块-请求方式

image-20241112233714916

Form表单

import requests
def form_post():# 请求地址url='http://localhost:8000/playground/add_role1'# 定义请求参数form_data = {'name':'孙权','book':'三国'}# 发送请求resp = requests.post(url,data=form_data)# 获取响应数据print(resp.text)

Json参数

def json_post():url ="http://localhost:8000/playground/add_role2"json_data = {'name':'典韦','book':'三国'}resp = requests.post(url,json=json_data)print(resp.text)

爬虫cookie的保存与使用

image-20220517201840354

代码

保存与使用

import requests
​
def get_cookies():url = 'http://localhost:8000/playground/login'data = {'uname':'admin','password':'123456'}s= requests.Session()resp = s.post(url,data=data)
​with open('cookies.txt','w') as f:for key,value in s.cookies.items():f.write(f'{key}:{value}\n')
​
def use_cookies():url = 'http://localhost:8000/playground/user_info'cookies = {}with open('cookies.txt','r') as f:for line in f.readlines():key,value = line.strip().split(':')cookies[key] = valueresp = requests.get(url,cookies=cookies)print(resp.text)
​
if __name__ == '__main__':get_cookies()use_cookies()

自动保持Cookie

import requests
​
def login():url = 'http://localhost:8000/playground/login'form_data ={'uname':'admin','password':'123456'}# 获取可以保存cookie的请求对象s = requests.Session()login_resp  = s.post(url,data=form_data)# print(login_resp.text)url = 'http://localhost:8000/playground/user_info'info_resp = s.get(url)print(info_resp.text)
​
if __name__ == '__main__':login()
​
​'''使用cookie1. 直接手动从浏览器复制,放到请求对象中2. 将cookie保存到本地,下次登录时,直接读取本地文件3. 使用session对象,自动保存cookie,连续性请求'''

爬虫Token的使用

image-20241114161408744

Token的基本概念是一种常见的HTTP认证方案,它使用安全令牌来进行身份验证。当服务器响应登录请求时,通常会生成这个token。

Token的使用场景

  • API接口认证
  • 需要登录的网站爬取
  • 受保护资源的访问

注意

Token有效期:很多token都有过期时间,需要及时更新

代码

import requests
​
def login():url = 'http://localhost:8000/playground/login2'json_data ={'uname':'admin','password':'123456'}resp = requests.post(url,json=json_data)token = resp.json().get('access_token')
​user_url = 'http://localhost:8000/playground/user_info2'resp = requests.get(user_url,headers={'Authorization':'Bearer '+token})print(resp.text)
​
if __name__ == '__main__':login()

数据的格式

  • HTML
  • JSON
  • 纯字符串
  • 2进制

Python使用正则

image-20220519165609474

常用方法

  • re.match(pattern, string, flags=0)

    • re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none
  • re.search(pattern, string, flags=0)

    • re.search 扫描整个字符串并返回第一个成功的匹配。
  • re.findall(pattern,string,flags=0)

    • re.findall 查找全部
  • re.sub(pattern,replace,string)

    • re.sub 替换字符串
import re
​
str ='I study python3.10 every_day'
print('----------------------match(规则,内容)-----------------------------') # 从头开始匹配,如果匹配上了返回值,如果匹配不上,返回none
m1 = re.match('I',str)
m2 = re.match('\w',str)
m3 = re.match('\S',str)
m4 = re.match('\D',str)
m5 = re.match('I (study)',str)
m6 = re.match('\w\s(\w*)',str)
print(m6.group(1))
​
print('----------------------search(规则,内容)-----------------------------') # 从任意位置开始匹配,,如果匹配上了返回值,如果匹配不上,返回none
s1 = re.search('I',str)
s2 = re.search('study',str)
s3 = re.search('p\w+',str)
s4 = re.search('p\w+.\d+',str)
print(s4.group())
​
print('----------------------findall(规则,内容)-----------------------------') # 从任意位置开始匹配,返回所有匹配的数据,如果没有匹配内容,返回一个空列表
f1 = re.findall('ddy',str)
print(f1)
​
print('----------------------sub(规则,替换的内容,内容)-----------------------------') # 替换原来的数据,并返回一个新的字符串,不会修改原来的字符串
print(re.sub('p\w+','Python',str))
print(str)
​
print('----------------------test()-----------------------------')
info = '<html><div><a href="http://www.itbaizhan.cn">百战程序员</a></div></html>'
tf = re.findall('<a href="(.+)">',info)
tf2 = re.findall('<a href=".+">(.+)</a>',info)
print(tf2)

正则表达式实战

image-20241115143945759

import re        # python内置
import requests     # 三方模块
​
# 访问的地址
url = 'http://localhost:8000/playground/1'
# 发送请求
resp = requests.get(url)
# 提取数据
title = re.findall('<h3 class="cyber-title">(.+?)</h3>',resp.text)
print(title)
sub_title = re.findall('<h5>(.+?)</h5>',resp.text)
print(sub_title)
content = re.findall('<p>(.+?)</p>',resp.text)
print(content)
​
info = re.findall('<p class="article-text.*?">(.+?)</p>',resp.text)
print(info)

数据解析-Beautiful Soup的使用

image-20220519171030193

简介

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序

Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,仅仅需要说明一下原始编码方式就可以了

Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度

官网http://beautifulsoup.readthedocs.io/zh_CN/latest/

Beautiful Soup 安装

pip install beautifulsoup4
pip install bs4

Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装

pip install lxml
解析器使用方法优势劣势
Python标准库BeautifulSoup(markup, “html.parser”)1. Python的内置标准库 2. 执行速度适中 3.文档容错能力强Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器BeautifulSoup(markup, “lxml”)1. 速度快 2.文档容错能力强需要安装C语言库
lxml XML 解析器BeautifulSoup(markup, [“lxml”, “xml”]) BeautifulSoup(markup, “xml”)1. 速度快 2.唯一支持XML的解析器 3.需要安装C语言库
html5libBeautifulSoup(markup, “html5lib”)1. 最好的容错性 2.以浏览器的方式解析文档 3.生成HTML5格式的文档 4.速度慢不依赖外部扩展

创建 Beautiful Soup 对象

from bs4 import BeautifulSoup
​
bs = BeautifulSoup(html,"lxml")

三大对象种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

  • Tag
  • NavigableString
  • Comment

案例代码

<title>尚学堂</title>
<div class='info' float='left'>Welcome to SXT</div>
<div class='info' float='right'><span>Good Good Study</span><a href='www.bjsxt.cn'></a><strong><!--没用--></strong>
</div>
Tag

通俗点讲就是 HTML 中的一个个标签

例如:<div> <title>

#以lxml方式解析
soup = BeautifulSoup(info, 'lxml')
print(soup.title)
# <title>尚学堂</title>

注意

相同的标签只能获取第一个符合要求的标签

获取属性
#获取所有属性
print(soup.title.attrs)
#class='info' float='left'
​
#获取单个属性的值
print(soup.div.get('class'))
print(soup.div['class'])
print(soup.a['href'])
#info
print(soup.title.string)
print(soup.title.text)
#尚学堂
Comment

Comment 对象是一个特殊类型的 NavigableString 对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦

if type(soup.strong.string) == Comment:print(soup.strong.prettify())
else:print(soup.strong.string)

数据解析-Beautiful Soup方法的使用

image-20220519171917906

find_all() 搜索文档树

Beautiful Soup定义了很多搜索方法,这里着重介绍find_all() 其它方法的参数和用法类似

字符串

传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容

#返回所有的div标签
print(soup.find_all('div'))
正则表达式

传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容

#返回所有的div标签
print (soup.find_all(re.compile("^div")))
列表

传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回

#返回所有匹配到的span a标签
print(soup.find_all(['span','a']))
keyword

传入一个id 的参数,Beautiful Soup会搜索每个tag的”id”属性

#返回id为welcom的标签
print(soup.find_all(id='welcome'))
True

True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点

按CSS搜索

传入一个css,通过 class_ 参数搜索有指定CSS类名的tag

# 返回class等于info的div
print(soup.find_all('div',class_='info'))
按属性的搜索
soup.find_all("div", attrs={"class": "info"})

CSS选择器

soup.select(参数)

表达式说明
tag选择指定标签
*选择所有节点
#id选择id为container的节点
.class选取所有class包含container的节点
li a选取所有li下的所有a节点
ul + p(兄弟)选择ul后面的第一个p元素
div#id > ul(父子)选取id为id的div的第一个ul子元素
table ~ div选取与table相邻的所有div元素
a[title]选取所有有title属性的a元素
a[class=”title”]选取所有class属性为title值的a
a[href*=”sxt”]选取所有href属性包含sxt的a元素
a[href^=”http”]选取所有href属性值以http开头的a元素
a[href$=”.png”]选取所有href属性值以.png结尾的a元素
input[type="redio"]:checked选取选中的hobby的元素

BS4实战

image-20241115143945759

# pip install bs4==4.12.3
# pip install lxml==5.3.0
import requests
from bs4 import BeautifulSoup
​
# 访问地址
url = 'http://localhost:8000/playground/1'
# 发送请求,获取响应
resp = requests.get(url)
# 创建bs4对象
bs = BeautifulSoup(resp.text,'lxml')
​
# 提取数据
title = bs.select('h3')
for t in title:print(t.text)
​
# 获取子标题
sub_title = bs.select('h5')
for s in sub_title:print(s.text)
​
# 获取子内容
content = bs.select('div.cyber-card > p')
for c in content:print(c.text)
​
# 获取段落信息
info = bs.select('p.article-text')
for i in info:print(i.text)

数据解析-xpath的使用

image-20220519170331557

介绍

之前 BeautifulSoup 的用法,这个已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法。如果大家对 BeautifulSoup 使用不太习惯的话,可以尝试下 Xpath

官网 http://lxml.de/index.html

w3c http://www.w3school.com.cn/xpath/index.asp

XPath语法

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上

节点的关系
  • 父(Parent)
  • 子(Children)
  • 同胞(Sibling)
  • 先辈(Ancestor)
  • 后代(Descendant)
常用的路径表达式
表达式描述
nodename选取此节点的所有子节点
/从根节点选取
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
.选取当前节点
..选取当前节点的父节点
@选取属性
通配符

XPath 通配符可用来选取未知的 XML 元素。

通配符描述举例结果
*匹配任何元素节点xpath('div/*')获取div下的所有子节点
@匹配任何属性节点xpath('div[@*]')选取所有带属性的div节点
node()匹配任何类型的节点
选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径

表达式结果
xpath('//div|//table')获取所有的div与table节点
谓语

谓语被嵌在方括号内,用来查找某个特定的节点或包含某个制定的值的节点

表达式结果
xpath('/body/div[1]')选取body下的第一个div节点
xpath('/body/div[last()]')选取body下最后一个div节点
xpath('/body/div[last()-1]')选取body下倒数第二个节点
xpath('/body/div[positon()<3]')选取body下前两个div节点
xpath('/body/div[@class]')选取body下带有class属性的div节点
xpath('/body/div[@class="main"]')选取body下class属性为main的div节点
xpath('/body/div[price>35.00]')选取body下price元素大于35的div节点
运算符
运算符描述实例返回值
计算两个节点集//book//cd
+加法6 + 410
减法6 – 42
*乘法6 * 424
div除法8 div 42
=等于price=9.80如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。
!=不等于price!=9.80如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
<小于price<9.80如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
<=小于或等于price<=9.80如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
>大于price>9.80如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
>=大于或等于price>=9.80如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。
orprice=9.80 or price=9.70如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。
andprice>9.00 and price<9.90如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。
mod计算除法的余数5 mod 21
选择XML文件中节点:
  • element(元素节点)
  • attribute(属性节点)
  • text() (文本节点)
  • concat(元素节点,元素节点)
  • comment (注释节点)
  • root (根节点)

XPath工具

image-20220605180512394

浏览器-元素-Ctrl+F

image-20220605110910646

浏览器-控制台-$x(表达式)

image-20220605110744146

Xpath helper (安装包需要科学上网)

image-20220605112721141

问题

使用离线安装包 出现 程序包无效

image-20220605115548881


解决方案

使用修改安装包的后缀名为 rar,解压文件到一个文件夹,再用加载文件夹的方式安装即可

安装

python若使用需要安装lxml模块

pip install lxml==5.3.0

JSON数据使用

image-20220519185156320

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。

同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互

JSON和XML的比较可谓不相上下

Python 中自带了JSON模块,直接import json就可以使用了

官方文档:http://docs.python.org/library/json.html

Json在线解析网站:http://www.json.cn/#

json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构

  1. 对象:对象在js中表示为{ }括起来的内容,数据结构为 { key:value, key:value, ... }的键值对的结构。

    在面向对象的语言中,key为对象的属性,value为对应的属性值。

    取值方法为 对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象这几种

  2. 数组:数组在js中是中括号[ ]括起来的内容,数据结构为 ["Python", "javascript", "C++", ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种

Python中的json模块

json模块提供了四个功能:

  • dumps
  • dump
  • loads
  • load
json.loads()

把Json格式字符串解码转换成Python对象 从json到python的类型转化对照如下:

import json
​
strList = '[1, 2, 3, 4]'
strDict = '{"city": "北京", "name": "范爷"}'
json.loads(strList) 
# [1, 2, 3, 4]
json.loads(strDict) # json数据自动按Unicode存储
# {u'city': u'\u5317\u4eac', u'name': u'\u5927\u732b'}
json.dumps()

实现python类型转化为json字符串,返回一个str对象 把一个Python对象编码转换成Json字符串

从python原始类型向json类型的转化对照如下:

import json
​
listStr = [1, 2, 3, 4]
tupleStr = (1, 2, 3, 4)
dictStr = {"city": "北京", "name": "范爷"}
​
json.dumps(listStr)
# '[1, 2, 3, 4]'
json.dumps(tupleStr)
# '[1, 2, 3, 4]'
​
# 注意:json.dumps() 序列化时默认使用的ascii编码
# 添加参数 ensure_ascii=False 禁用ascii编码,按utf-8编码
​
json.dumps(dictStr) 
# '{"city": "\\u5317\\u4eac", "name": "\\u5927\\u5218"}'
​
print(json.dumps(dictStr, ensure_ascii=False))
# {"city": "北京", "name": "范爷"}
​
json.dump()

将Python内置类型序列化为json对象后写入文件

import json
​
listStr = [{"city": "北京"}, {"name": "范爷"}]
json.dump(listStr, open("listStr.json","w"), ensure_ascii=False)
​
dictStr = {"city": "北京", "name": "范爷"}
json.dump(dictStr, open("dictStr.json","w"), ensure_ascii=False)
json.load()

读取文件中json形式的字符串元素 转化成python类型

import json
​
strList = json.load(open("listStr.json"))
print(strList)
​
# [{u'city': u'\u5317\u4eac'}, {u'name': u'\u5927\u5218'}]
​
strDict = json.load(open("dictStr.json"))
print(strDict)
# {u'city': u'\u5317\u4eac', u'name': u'\u5927\u5218'}

注意事项

  • json.loads() 是把 Json格式字符串解码转换成Python对象,如果在json.loads的时候出错,要注意被解码的Json字符的编码。 如果传入的字符串的编码不是UTF-8的话,需要指定字符编码的参数 encoding

data_dict = json.loads(jsonStrGBK);

dataJsonStr是JSON字符串,假设其编码本身是非UTF-8的话而是GBK 的,那么上述代码会导致出错,改为对应的:

data_dict = json.loads(jsonStrGBK, encoding="GBK");

如果 dataJsonStr通过encoding指定了合适的编码,但是其中又包含了其他编码的字符,则需要先去将dataJsonStr转换为Unicode,然后再指定编码格式调用json.loads()

dataJsonStrUni = dataJsonStr.decode("GB2312"); 
dataDict = json.loads(dataJsonStrUni, encoding="GB2312");

JsonPath的使用

image-20220519185752639

JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Python,Javascript, PHP 和 Java。

JsonPath 对于 JSON 来说,相当于 XPATH 对于 XML。

安装

pip install jsonpath==0.82.2

官方文档:http://goessner.net/articles/JsonPath

JsonPath与XPath语法对比

Json结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath的用法

XPathJSONPath描述
/$根节点
.@当前节点
/.or[]取子节点
..n/a取父节点,Jsonpath未支持
//..就是不管位置,选择所有符合条件的条件
**匹配所有元素节点
@n/a根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要。
[][]迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)
|[,]支持迭代器中做多选。
[]?()支持过滤操作.
n/a()支持表达式计算
()n/a分组,JsonPath不支持

代码

# pip install jsonpath==0.82.2
from jsonpath import jsonpath
import requests
​
# 访问地址
url = 'http://localhost:8000/api/movies?page=1&movie_type=&movie_time='
resp = requests.get(url)
# 获取json的响应结果
data = resp.json()
# 提取数据
movie_title = jsonpath(data,'$..movie_name')
movie_type = jsonpath(data,'$..movie_type')
for title,type in zip(movie_title,movie_type):print(title,'=====',type)
​
# 注意:jsonpath表达式要从$开头

http://www.dtcms.com/a/393662.html

相关文章:

  • Rabbitmq 集群初始化,配置导入
  • 云计算与虚拟化技术详解
  • elasticsearch 的配制
  • React学习教程,从入门到精通,React Hook 详解 —— 语法知识点、使用方法与案例代码(26)
  • ELK日志分析性能瓶颈问题排查与解决实践指南
  • 【Unity】【Photon】Fusion2中的匹配API 学习笔记
  • (3-1) Html
  • 《人机协同的边界与价值:开放世界游戏系统重构中的AI工具实战指南》
  • 数据库造神计划第十九天---事务(2)
  • Python到剪映草稿生成及导出工具,构建全自动化视频剪辑/混剪流水线
  • WordPress给指定分类文章添加一个自动化高亮(一键复制)功能
  • 5分钟使用Dify实现《射雕英雄传》问答智能体Agent
  • 3. 认识 const
  • 云原生 vs 传统部署
  • 2.1、机器学习-模型评估指标与参数调优
  • 设计模式(C++)详解—享元模式(2)
  • Linux实用操作以及基础命令
  • 深入理解 Vue 插槽:从基础到高级用法
  • 自动排班系统:劳动力管理新选择
  • Word和WPS文字中设置了倍数行距却没有变化?原因和调整方法
  • 【Linux篇】Linux 初探:历史溯源与常用指令速览
  • 数字孪生及其在能源和新材料等领域内的应用
  • DeepSeek后训练:监督微调策略,开启模型优化新时代
  • 基于规则的专家系统对自然语言处理深层语义分析的影响与启示研究
  • 设计模式学习[19]---单例模式(饿汉式/懒汉式)
  • 基于哈希表与差分前缀和解决撒狗粮问题
  • 基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
  • 残差分析:数据驱动下线性模型的“体检师”与优化指南
  • gorm速成
  • 模型和策略:风控体系的“左右手”之争