前言
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。和XML相比,JSON更加简洁和易于读写,同时也更加易于解析和生成。JSON的基本数据类型包括字符串、数字、布尔、null以及数组和对象两种复合类型。各种编程语言都可以很方便地生成和解析JSON数据。
Python中内置了一个JSON模块,可以很方便地进行JSON数据的生成和解析。该模块包括四个函数:dumps、dump、loads和load,分别用于将Python对象转换为JSON格式的字符串、将Python对象转换为JSON格式并存储到一个文件中、将JSON字符串转换为Python对象和将JSON格式的文件读取并转换为Python对象。
json库是处理JSON格式的Python标准库,json库主要包括两类函数:操作函数和解析函数。
(1)操作函数:主要完成外部JSON格式和程序内部数据类型之间的转换功能。
(2)解析函数:主要用于解析键值对内容
(3)json格式包括对象和数组,用大括号{}和方括号[]表示,分别对应键值对的组合关系和对等关系,使用json库时需要注意json格式的“对象”和"数组"概念与Python语言中"字典"和"列表"的区别于联系。
(4)一般来说,JSON格式的对象将被json库解析为字典,JSON格式的数组将被解析为列表。
json包含两个过程,那就是编码和解码。编码是将Python数据类型变换成JSON格式,解码是从JSON格式中解析数据对应到Python数据类型的过程。
四个常用方法总结:
dump( ) | 将Python对象转换为JSON格式并存储到一个文件中 |
dumps( ) | 将Python对象转换为JSON格式的字符串 |
load( ) | 将JSON字符串转换为Python对象 |
loads( ) | 将JSON格式的文件读取并转换为Python对象 |
1. 将Python对象转换为json字符串
import json
data = [{'hive': 1, 'hadoop': 2, 'hbase': 3, 'flink': 4, 'ambari': 5}]
print("data数据类型: ", type(data))
# 将一个Python数据类型列表进行json格式的编码
data2 = json.dumps(data)
print("data2数据类型: ", type(data2))
print(data2)
jsonStr = json.dumps(arr)
2. 将Python对象转换为json数据并保存到文件中
使用dump方法可以将Python的字典对象转为json数据后并输出到文件中,下面代码实现读取Excel文件,并将读取的数据转换为json数据并保存到json文件中
import xlrd
import json
workbook = xlrd.open_workbook("E:\\studyproject\\python\\Excel数据读取\\费县摸排数据\\水源地.xls")
worksheet = workbook.sheet_by_name('Sheet1')
# 获取所有行数和列数
rows = worksheet.nrows
cols = worksheet.ncols
arr = []
for row in range(rows):
obj = {}
for col in range(cols):
obj[worksheet.cell_value(0, col)] = worksheet.cell_value(row, col)
arr.append(obj)
fp = open('geo.json','w',encoding='utf-8')
jsonStr = json.dumps(arr)
json.dump(arr,fp,ensure_ascii=False)
注意:导出json文件是,json数据中文编码为unicode问题,这个时候需要在open()时设置encoding='utf-8‘参数,在dump方法中传入参数ensure_ascii=False
3. 将json字符串序列化为Python对象
使用Python进行接口数据爬取时,接口经常返回json数据格式,下面的代码示例中使用loads()函数将Python爬取今日头条文章列表接口返回的json数据转换为Python对象,并保存到数据库中。
# 浏览器自动化工具
from selenium import webdriver
from selenium.webdriver.common.by import By
# 时间工具
from time import sleep
from time import time
# 网络请求工具
import requests
# JSON解析工具
import json
# 数据库链接工具
import pymysql
# re库
import re
# 创建一个浏览器实例
#browser = webdriver.Chrome() #谷歌
browser = webdriver.Firefox()
# 获取请求地址
browser.get("file:///E:/studyproject/python/toutiao/getSig.html")
#链接MySQL
mysqlCon = pymysql.connect(
host="127.0.0.1",
port=3306,
user="root",
password="123456",
database="toutiao"
)
# 匹配模版
matchTemplate = ""
sleep(10)
while True:
# 自动化获取js代码计算的sig数据值
sigTag = browser.find_element(By.ID,"sigUrl")
url = sigTag.text
headers = {
# 设置User-Agent,模拟浏览器发送请求
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
# 设置Cookie,用于身份验证或其他需要的信息
'Cookie': '__ac_signature=_02B4Z6wo00f01Lz3yHgAAIDB3.0IExdN.9i818zAAEpR33;tt_webid=7309719685489198604;ttcid=fb73866ceb7a44cdb848344abfc11b6364;s_v_web_id=verify_lpur8vrr_aKDsfWBn_AThk_4UlU_8RpK_Ci9lGCzIBKbb; _ga=GA1.1.1051493470.1701926754; local_city_cache=%E4%B8%B4%E6%B2%82; csrftoken=4561fa578aa7c7bc7d3ac8f87ac7fad1; __feed_out_channel_key=entertainment; passport_csrf_token=a296ea89de4f632e00534cd16812d593; passport_csrf_token_default=a296ea89de4f632e00534cd16812d593; msToken=Lhx7DAYTtQJiiCVIVmYNqtpQkUVKq8RzEzhUZAslgKw_w5gJ_vSlmCJKsQoQUyXXoJzHhluRQFpfceUoT2n2IoACypVJ-aD7RCuXC7iI; tt_scid=0lfkb7lPohYDsWmjDuFAe7L3oLDo0KsbKzlhKzl1CQ2im2TQypCzPCKr.jkBHxexd641; ttwid=1%7CVPO9aK7JwsvyYUFWA3MR5i_pw1b4nic0TD5-jp-zjVc%7C1702450449%7C067c9bd8be4c0a21dc4e60bc225ee29072184eeb24503d5d6cc26b9554d20d26; _ga_QEHZPBE5HH=GS1.1.1702455638.13.0.1702455638.0.0.0.0.0'
}
# 请求接口获取json数据
res = requests.get(url,headers=headers)
json_obj = json.loads(res.text)
# 通过遍历每条数据,过滤热门文章
for item in json_obj['data']:
# 计算文章分享数量
shareCount = item['share_info']['share_type']['pyq']+item['share_info']['share_type']['qq']+item['share_info']['share_type']['qzone']+item['share_info']['share_type']['wx']
imageList = ""
# 判断文章路径是否是站内文章路径
if re.match(matchTemplate,item['article_url']):
# 多条件判断是否是较新的热门文章
if item['read_count'] >= 3000:
# 创建游标对象
cursor = mysqlCon.cursor()
# 执行 SQL 查询语句
cursor.execute("select * from happy where item_id ="+item['item_id'])
# 获取查询结果
result = cursor.fetchall()
# 判断是否已经插入
if len(result) == 0:
# 将热门文章保存到数据库
sql = "insert into happy (id,item_id,title,abstract,publish_time,like_count,read_count,comment_count,share_count,image_list,article_url,gather_time,transport_time,source) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
values = (None,item['item_id'],item['title'],item['Abstract'],item['publish_time'],item['like_count'],item['read_count'],item['comment_count'],shareCount,imageList,item['article_url'],time(),0,"toutiao")
cursor.execute(sql,values)
mysqlCon.commit()
else:
print("已经存在")
# 固定时间获取一次url地址
sleep(180)
# 关闭数据库链接
# cursor.close()
# mysqlCon.close()
sleep(5)
browser.quit()