目录
[浏览器- 开发者工具](#浏览器- 开发者工具)
[数据解析-Beautiful Soup的使用](#数据解析-Beautiful Soup的使用)
[Beautiful Soup 安装](#Beautiful Soup 安装)
[创建 Beautiful Soup 对象](#创建 Beautiful Soup 对象)
[数据解析-Beautiful Soup方法的使用](#数据解析-Beautiful Soup方法的使用)
[find_all() 搜索文档树](#find_all() 搜索文档树)
爬虫介绍

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

简单的说:就是用代码模拟人的行为,去各各网站溜达、点点按钮、查查数据。或者把看到的数据拿下来。
爬虫有什么作用?
通过有效的爬虫手段批量采集数据,可以降低人工成本,提高有效数据量,给予运营/销售的数据支撑,加快产品发展。



爬虫应用领域
- 批量采集某个领域的招聘数据,对某个行业的招聘情况进行分析
- 批量采集某个行业的电商数据,以分析出具体热销商品,进行商业决策 • 采集目标客户数据,以进行后续营销
- 批量爬取腾讯动漫的漫画,以实现脱网本地集中浏览
- 开发一款火车票抢票程序,以实现自动抢票
- 爬取评论,舆情监控
- 爬取说说信息,分析上线时间
- ...
业界的情况如何
目前互联网产品竞争激烈,业界大部分都会使用爬虫技术对竞品产品的数据进行挖掘、采集、大数据分析,这是必备手段,并且部分公司都设立了爬虫工程师
的岗位
爬虫的合法性

民间流传出下面一段话:
爬虫爬得欢,监狱要坐穿; 数据玩的溜,牢饭吃个够

问题
爬虫是否是合法的呢?
答案
有时合法,有时不合法,因情况而定
爬虫是利用程序进行批量爬取网上的公开信息,也就是前端显示的数据信息。因为信息是完全公开的,所以是常规合法的!!!
合法的爬虫
- 公开的数据,没有标识不可爬取
- 不影响别人服务器
- 不影响的业务
不合法的爬虫
-
用户数据
-
部分网站、APP数据超过指定数量
-
明文规定不让爬取
- 在域名后加上
/robots.txt
查看 - 页面上标明
- 在域名后加上
-
影响业务
-
影响服务器
类似DDOS攻击的问题
提示
部分爬虫虽然违法,但公司、或企业不会直接报警。会采用反爬的手段,严重后才会报警
反爬与反反爬

反爬:有时企业不想自己的数据被别人拿到。这时就会设置反爬的手段,来不让爬虫获取数据。
反爬虫常用一些手段:
- 合法检测:请求校验(useragent,referer,接口加签 ,等)
- 验证码:识别文字、做题、滑动等
- 小黑屋:IP/用户限制请求频率,或者直接拦截
- 投毒:反爬虫高境界可以不用拦截,拦截是一时的,投毒返回虚假数据,可以误导竞品决策
- ... ...
反反爬:破解掉反爬手段,再获取其数据。所有的手段都能破解吗?
道高一尺魔高一丈,这是一场没有硝烟的战争,程序员VS程序员
爬虫的基本套路

-
基本流程
-
目标数据:想要什么数据
-
来源地址
-
结构分析
- 具体数据在哪(网站、还是APP)
- 如何展示的数据
-
实现构思
-
操刀编码
-
-
基本手段
-
破解请求限制
- 请求头设置,如:useragant为有效客户端
- 控制请求频率(根据实际情景)
- IP代理
- 签名/加密参数从html/cookie/js分析
-
破解登录授权
- 请求带上用户cookie信息
-
破解验证码
- 简单的验证码可以使用识图读验证码第三方库
-
-
解析数据
-
HTML Dom解析
- 正则匹配,通过的正则表达式来匹配想要爬取的数据,如:有些数据不是在html 标签里,而是在html的script 标签的js变量中
- 使用第三方库解析html dom,比较喜欢类jquery的库
-
数据字符串
- 正则匹配(根据情景使用)
- 转 JSON/XML 对象进行解析
-
选择一门语言
爬虫可以用各种语言写, C++, Java都可以, 为什么要Python?
- 简单
- 高效
- 三方模块库多
浏览器- 开发者工具

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



爬虫靶场
爬虫靶场的主要作用:
-
学习和练习
- 为开发者提供一个安全的环境来练习网页爬虫技术
- 可以测试不同的爬虫策略和技术,而不用担心影响真实网站
- 适合新手学习基础爬虫概念和技术
-
测试和调试
- 可以测试爬虫程序在各种场景下的表现
- 帮助开发者发现和解决爬虫代码中的问题
- 验证爬虫的稳定性和可靠性
通过使用爬虫靶场,开发者可以:
- 在安全的环境中提升爬虫开发技能
- 为实际项目积累经验和最佳实践
访问方式
-
直接访问
-
docker 部署,具体步骤如下:
python
# 下载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
第一个爬虫

数据来源
- 网站
- 移动端
小试牛刀
怎样扒网页呢?
其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS、CSS。如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML
- HTML 70%
- JS 20%
- CSS 10%

爬取页面,代码如下:
python
from urllib.request import urlopen
response = urlopen("http://www.baidu.com/")
print(response.read().decode())
注意
urllib模块库是python自带的。在Python2叫urllib2
真正的程序就两行,执行如下命令查看运行结果,感受一下
看,这个网页的源码已经被我们扒下来了,是不是很酸爽?
requests模块-请求方式

文档地址
https://requests.readthedocs.io/
安装
利用 pip 安装
python
pip install requests==2.32.3
基本请求
python
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模块-请求方式

Form表单
python
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参数
python
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的保存与使用

代码
保存与使用
python
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] = value
resp = requests.get(url,cookies=cookies)
print(resp.text)
if __name__ == '__main__':
get_cookies()
use_cookies()
自动保持Cookie
python
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()
'''
使用cookie
1. 直接手动从浏览器复制,放到请求对象中
2. 将cookie保存到本地,下次登录时,直接读取本地文件
3. 使用session对象,自动保存cookie,连续性请求
'''
爬虫Token的使用

Token的基本概念是一种常见的HTTP认证方案,它使用安全令牌来进行身份验证。当服务器响应登录请求时,通常会生成这个token。
Token的使用场景
- API接口认证
- 需要登录的网站爬取
- 受保护资源的访问
注意
Token有效期:很多token都有过期时间,需要及时更新
代码
python
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使用正则

常用方法
-
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 替换字符串
python
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)
正则表达式实战

python
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的使用

简介
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,仅仅需要说明一下原始编码方式就可以了
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度
官网http://beautifulsoup.readthedocs.io/zh_CN/latest/
Beautiful Soup 安装
python
pip install beautifulsoup4
pip install bs4
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装
python
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语言库 | |
html5lib | BeautifulSoup(markup, "html5lib") | 1. 最好的容错性 2.以浏览器的方式解析文档 3.生成HTML5格式的文档 4.速度慢 | 不依赖外部扩展 |
创建 Beautiful Soup 对象
python
from bs4 import BeautifulSoup
bs = BeautifulSoup(html,"lxml")
三大对象种类
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
- Tag
- NavigableString
- Comment
案例代码
python
<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>
python
#以lxml方式解析
soup = BeautifulSoup(info, 'lxml')
print(soup.title)
# <title>尚学堂</title>
注意
相同的标签只能获取第一个符合要求的标签
获取属性
python
#获取所有属性
print(soup.title.attrs)
#class='info' float='left'
#获取单个属性的值
print(soup.div.get('class'))
print(soup.div['class'])
print(soup.a['href'])
#info
NavigableString获取内容
python
print(soup.title.string)
print(soup.title.text)
#尚学堂
Comment
Comment 对象是一个特殊类型的 NavigableString 对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦
python
if type(soup.strong.string) == Comment:
print(soup.strong.prettify())
else:
print(soup.strong.string)
数据解析-Beautiful Soup方法的使用

find_all() 搜索文档树
Beautiful Soup定义了很多搜索方法,这里着重介绍find_all() 其它方法的参数和用法类似
字符串
传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容
python
#返回所有的div标签
print(soup.find_all('div'))
正则表达式
传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容
python
#返回所有的div标签
print (soup.find_all(re.compile("^div")))
列表
传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回
python
#返回所有匹配到的span a标签
print(soup.find_all(['span','a']))
keyword
传入一个id 的参数,Beautiful Soup会搜索每个tag的"id"属性
python
#返回id为welcom的标签
print(soup.find_all(id='welcome'))
True
True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
按CSS搜索
传入一个css,通过 class_ 参数搜索有指定CSS类名的tag
python
# 返回class等于info的div
print(soup.find_all('div',class_='info'))
按属性的搜索
python
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实战

python
# 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的使用

介绍
之前 BeautifulSoup 的用法,这个已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法。如果大家对 BeautifulSoup 使用不太习惯的话,可以尝试下 Xpath
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') |
谓语
谓语被嵌在方括号内,用来查找某个特定的节点或包含某个制定的值的节点
表达式 | 结果 |
---|---|
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 + 4 | 10 |
-- |
减法 | 6 -- 4 | 2 |
* |
乘法 | 6 * 4 | 24 |
div |
除法 | 8 div 4 | 2 |
= |
等于 | 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。 |
or |
或 | price=9.80 or price=9.70 | 如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。 |
and |
与 | price>9.00 and price<9.90 | 如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。 |
mod |
计算除法的余数 | 5 mod 2 | 1 |
选择XML文件中节点:
- element(元素节点)
- attribute(属性节点)
- text() (文本节点)
- concat(元素节点,元素节点)
- comment (注释节点)
- root (根节点)
XPath工具

浏览器-元素-Ctrl+F

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

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

问题
使用离线安装包 出现 程序包无效
解决方案
使用修改安装包的后缀名为 rar,解压文件到一个文件夹,再用加载文件夹的方式安装即可
安装
python若使用需要安装lxml模块
python
pip install lxml==5.3.0
JSON数据使用

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。
同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互
JSON和XML的比较可谓不相上下
Python 中自带了JSON模块,直接import json
就可以使用了
官方文档:http://docs.python.org/library/json.html
Json在线解析网站:http://www.json.cn/#
json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构
-
对象:对象在js中表示为{ }括起来的内容,数据结构为 { key:value, key:value, ... }的键值对的结构。
在面向对象的语言中,key为对象的属性,value为对应的属性值。
取值方法为 对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象这几种
-
数组:数组在js中是中括号[ ]括起来的内容,数据结构为 ["Python", "javascript", "C++", ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种
Python中的json模块
json模块提供了四个功能:
- dumps
- dump
- loads
- load
json.loads()
把Json格式字符串解码转换成Python对象 从json到python的类型转化对照如下:
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类型的转化对照如下:
python
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对象后写入文件
python
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类型
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
python
data_dict = json.loads(jsonStrGBK);
dataJsonStr是JSON字符串,假设其编码本身是非UTF-8的话而是GBK 的,那么上述代码会导致出错,改为对应的:
python
data_dict = json.loads(jsonStrGBK, encoding="GBK");
如果 dataJsonStr通过encoding指定了合适的编码,但是其中又包含了其他编码的字符,则需要先去将dataJsonStr转换为Unicode,然后再指定编码格式调用json.loads()
python
dataJsonStrUni = dataJsonStr.decode("GB2312");
dataDict = json.loads(dataJsonStrUni, encoding="GB2312");
JsonPath的使用

JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Python,Javascript, PHP 和 Java。
JsonPath 对于 JSON 来说,相当于 XPATH 对于 XML。
安装
python
pip install jsonpath==0.82.2
官方文档:http://goessner.net/articles/JsonPath
JsonPath与XPath语法对比
Json结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath的用法
XPath | JSONPath | 描述 |
---|---|---|
/ |
$ |
根节点 |
. |
@ |
当前节点 |
/ |
. or[] |
取子节点 |
.. |
n/a |
取父节点,Jsonpath未支持 |
// |
.. |
就是不管位置,选择所有符合条件的条件 |
* |
* |
匹配所有元素节点 |
@ |
n/a |
根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要。 |
[] |
[] |
迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
` | ` | [,] |
[] |
?() |
支持过滤操作. |
n/a |
() |
支持表达式计算 |
() |
n/a |
分组,JsonPath不支持 |
代码
python
# 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表达式要从$开头