Python中怎么利用json爬虫:从数据获取到解析的实战指南
在Python爬虫开发中,JSON(JavaScript Object Notation)因其轻量级、易读性强、与Python字典结构高度兼容的特点,成为网页数据交互的主流格式,许多现代API和动态加载网站的数据源都以JSON形式返回,JSON爬虫的技巧能显著提升爬取效率和准确性,本文将详细介绍Python中利用JSON爬虫的核心流程,包括数据获取、解析、存储及常见问题解决,并通过实战代码演示具体操作。
JSON爬虫的核心优势
与传统HTML解析相比,JSON爬虫具有明显优势:
- 结构化数据:JSON数据以键值对形式组织,字段清晰,无需像HTML解析那样处理复杂的标签嵌套;
- 解析效率高:Python内置
json
模块可直接解析JSON字符串,无需依赖第三方解析库(如BeautifulSoup对HTML的解析); - 数据准确性高:JSON数据格式规范,字段名固定,能避免因HTML结构变动导致的解析失败;
- 适合动态数据:现代网站常通过AJAX异步加载JSON数据,直接请求JSON接口可减少页面渲染开销,提高爬取速度。
Python JSON爬虫核心流程
JSON爬虫的核心流程可分为四步:发送请求获取JSON数据 → 解析JSON数据 → 提取目标字段 → 存储数据,下面结合代码逐步拆解。
发送请求获取JSON数据
爬取JSON数据的第一步是模拟浏览器向目标URL发送HTTP请求,常用的Python库有requests
(推荐,简洁高效)和urllib
(标准库,功能稍弱)。
示例:使用requests
获取JSON数据
以公开的API接口为例(如“随机笑话API”:https://api.xygeng.cn/one
),该接口返回JSON格式的笑话数据:
import requests import json # 目标JSON接口URL url = "https://api.xygeng.cn/one" # 发送GET请求(部分接口需POST请求,可设置method="POST") headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } # 模拟浏览器头部,避免被反爬 try: response = requests.get(url, headers=headers, timeout=10) # 设置超时时间 response.raise_for_status() # 检查请求是否成功(状态码200) # 获取JSON数据(response.json()会自动解析JSON为Python字典) json_data = response.json() print("原始JSON数据:", json_data) except requests.exceptions.RequestException as e: print(f"请求失败:{e}")
关键点:
- User-Agent:模拟浏览器访问,避免被识别为爬虫;
- 超时设置:避免因网络问题导致程序卡死;
- 异常处理:捕获网络请求异常(如超时、404、500等)。
解析JSON数据
Python内置json
模块提供了JSON数据的解析和生成功能。requests
库的response.json()
方法已将JSON字符串自动解析为Python字典,可直接操作。
示例:解析嵌套JSON数据
假设JSON数据结构如下(以“天气API”为例):
{ "code": 200, "data": { "city": "北京", "weather": "晴", "temperature": 25, "humidity": 60 }, "msg": "success" }
解析代码:
import json # 假设这是从API获取的JSON字符串(实际中用response.json()获取) json_str = ''' { "code": 200, "data": { "city": "北京", "weather": "晴", "temperature": 25, "humidity": 60 }, "msg": "success" } ''' # 方法1:直接用response.json()(推荐,requests已自动解析) # json_data = response.json() # 方法2:手动解析(适用于非requests场景,如本地JSON文件) json_data = json.loads(json_str) # 将JSON字符串转为Python字典 # 提取字段 code = json_data["code"] # 顶层字段 city = json_data["data"]["city"] # 嵌套字段 temperature = json_data["data"]["temperature"] print(f"城市:{city}, 天气:{json_data['data']['weather']}, 温度:{temperature}℃")
关键点:
json.loads()
:将JSON字符串解析为Python字典;json.dumps()
:将Python字典/列表转为JSON字符串(常用于数据存储);- 嵌套字段通过
字典["key1"]["key2"]
方式逐层访问。
提取目标字段
解析后的JSON数据本质是Python字典,可通过键名直接提取目标字段,对于复杂结构(如列表嵌套字典),需结合循环和条件判断提取。
示例:提取列表中的JSON数据
假设JSON数据是一个列表,每个元素是一个字典(如“商品列表API”):
[ {"id": 1, "name": "苹果", "price": 5.99}, {"id": 2, "name": "香蕉", "price": 3.49}, {"id": 3, "name": "橙子", "price": 4.99} ]
提取代码:
import json json_str = ''' [ {"id": 1, "name": "苹果", "price": 5.99}, {"id": 2, "name": "香蕉", "price": 3.49}, {"id": 3, "name": "橙子", "price": 4.99} ] ''' json_data = json.loads(json_str) # 遍历列表提取所有商品信息 for product in json_data: product_id = product["id"] product_name = product["name"] product_price = product["price"] print(f"商品ID:{product_id}, 名称:{product_name}, 价格:{product_price}元")
关键点:
- 使用
for
循环遍历列表或字典的values()
/items()
; - 通过
if
条件过滤目标数据(如提取价格大于4元的商品)。
存储数据
提取后的数据需存储到文件或数据库中,常用格式有JSON文件、CSV文件、MySQL数据库等。
示例1:存储为JSON文件
import json # 假设这是提取后的数据(Python列表) data_to_save = [ {"id": 1, "name": "苹果", "price": 5.99}, {"id": 2, "name": "香蕉", "price": 3.49}, {"id": 3, "name": "橙子", "price": 4.99} ] # 写入JSON文件(ensure_ascii=False避免中文乱码,indent=4格式化缩进) with open("products.json", "w", encoding="utf-8") as f: json.dump(data_to_save, f, ensure_ascii=False, indent=4) print("数据已保存到products.json")
示例2:存储为CSV文件
import csv data_to_save = [ {"id": 1, "name": "苹果", "price": 5.99}, {"id": 2, "name": "香蕉", "price": 3.49}, {"id": 3, "name": "橙子", "price": 4.99} ] # 写入CSV文件 with open("products.csv", "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["id", "name", "price"]) # 指定字段名 writer.writeheader() # 写入表头 writer.writerows(data_to_save) # 写入数据行 print("数据已保存到products.csv")
关键点:
json.dump()
:直接将字典/列表写入JSON文件;csv.DictWriter()
:适合将字典列表写入CSV文件,需指定字段名;- 文件编码统一用
utf-8
,避免中文乱码。
实战案例:爬取“知乎热榜”JSON数据
知乎热榜通过AJAX异步加载JSON数据,接口URL为:https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50
,下面完整演示爬取流程。
分析接口
- 请求方法:GET
- 请求头:需添加
User-Agent
还没有评论,来说两句吧...