python 调用API接口 获取和解析 Json数据

任务背景:

调用API接口数据,抽取我们所需类型的数据,并写入指定mysql数据库。

先从宏观上看这个任务,并对任务进行分解:

step1:需要学习python下的通过url读取数据的方式;

step2:数据解析,也是核心部分,数据格式从python角度去理解,是字典?列表?还是各种嵌套?

step3:连接mysql数据库,将数据写入。

从功能上看,该数据获取程序可以分为3个方法,即step1对应方法request_data(),step2对应方法parse_data(),step3对应data_to_db()。

第一轮,暂不考虑异常,只考虑正常状态下的功能实现。

1、先看request_data():

 import requests
 def request_data(url):
 req = requests.get(url, timeout=30) # 请求连接
 req_jason = req.json() # 获取数据
 return req_jason 

入参:url地址;return:获取到的数据。

2、然后看parse_data():

不同的API接口下的数据格式各不相同,需要先理清,打开之后密密麻麻一大串,有的可能连完整的一轮数据间隔在哪都不知道,这时候可以巧用符号{ [ , ] }辅助判断。

梳理之后,发现本接口下的数据格式为,最外层为字典,我们所需的数据在第一个key“data”下,data对应的value为列表,列表中的每个元素为字典,字典中的部分键值

即为我们需要的内容。这样,就明确了我们的数据结构为字典套列表,列表再套字典的格式,最后一层的字典还存在一键多值(比如“weather”)的情况。

当然,还有懒人方法,就是百度json在线解析格式化。

摘取部分数据如下:{"data":[{"timestamp_utc":"2020-08-31T08:00:00","weather":{"icon":"c02d","code":802,
wind_dir":336,"clouds_hi":0,"precip":0.0625},{"timestamp_utc":"2020-08-31T08:00:00","weather":{"icon":"c02d","code":802,},
wind_dir":336,"clouds_hi":0,"precip":0.0625],"city_name":"Dianbu","lon":117.58,"timezone":"Asia\/Shanghai","lat":31.95,"country_code":"CN"}

def parse_data(req_jason):
 data_trunk = req_jason['data']# 获取data键值下的列表
 time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") #获取当前时刻
 for i in range(len(data_trunk)):
  data_unit = data_trunk[i] # 依次获取列表下第i个元素即字典
  del data_unit['weather'] # 删除该字典中不需要的一键多值的key和value,不删除的话会影响后续的dataframe转换,但是,如果该键值需要的话,需要采取其他处理方式
  df = pd.DataFrame([data_unit]) # 将删除键值后的字典转为datafrme
  list_need = ['timestamp_utc', 'wind_dir', 'precip','clouds_hi'] # 列出我们需要的列
  df_need = df[list_need] # 保留df中需要的列  10  df_need.insert(0, 'update_time', time_now) #表格中还需额外增加获取数据的当前时间,并且需要放在dataframe的第一列

备注:数据插入数据库,有两种方式,一种是采用insert的sql语句,采用字典的形式插入,另一种是采用dataframe的方式,采用pandas中的to_sql方法。本案例选择了后者,所以在数据解析时,将字典数据转成dataframe格式。

入参:获取到的数据;return值:无

运行以后,发现这样的程序存在一些问题:就是这个for循环括起来的过多,导致写数据库时是一条条写入而不是一整块写入,会影响程序效率,所以需要对程序进行如下修改:

def parse_data(req_jason):
 data_trunk = req_jason['data']# 获取data键值下的列表
 time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") #获取当前时刻
 for i in range(len(data_trunk)):
  data_unit = data_trunk[i] # 依次获取列表下第i个元素即字典
  del data_unit['weather'] # 删除该字典中不需要的一键多值的key和value,不删除的话会影响后续的dataframe转换,但是,如果该键值需要的话,需要采取其他处理方式
 df = pd.DataFrame(data_trunk) # 将删除键值后的整个列表套字典转为datafrme
 list_need = ['timestamp_utc', 'wind_dir', 'precip','clouds_hi'] # 列出我们需要的列
 df_need = df[list_need] # 保留df中需要的列
 df_need.insert(0, 'update_time', time_now) #表格中还需额外增加获取数据的当前时间,并且需要放在dataframe的第一列

也就是从第7行之后跳出循环;

如果觉得for循环影响整体美观,也可以用map代替,将代码第4/5/6行改为如下代码,不过性能上来说可能还是for循环更好,具体对比可看其他博主的测试,或者自己测试下运行时间。

map(data_trunk.pop, ['weather'])

3. 最后就是data_to_sql():

def data_to_sql(df):
 table = 'request_data_api'
 engine = create_engine("mysql+pymysql://" + 'root' + ":" + '123' + "@" + 'localhost' + ":" + '3306' + "/" + 'test' + "?charset=utf8")
 df.to_sql(name=table, con=engine, if_exists='append',
   index=False, index_label=False)

入参:dataframe类型数据。

当当当,正常部分已完成,就下来就需要想象各种异常以及处理对策。

第二轮,想象各种异常以及异常的记录与处理对策。

1.读取url后,获取不到数据 → 休息几秒,尝试再次重连获取

2.连接数据库异常 → 数据库可能关闭,尝试重新ping,

3.写入数据库的内容为空 → 记录异常,放弃入库

第三轮,让程序定时跑起来。

方法一:在代码中采用apscheduler下的cron功能(trigger='cron‘,类似linux下的crontab)实现定时运行(当然,apscheduler还有另一种trigger=‘interval'模式);

方法二:在linux下的crontab增加定时任务。

具体可以看别的帖子。

以上就是python 调用API接口 获取和解析 Json数据的详细内容,更多关于python 解析数据的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python多线程爬取豆瓣影评API接口

    爬虫库 使用简单的requests库,这是一个阻塞的库,速度比较慢. 解析使用XPATH表达式 总体采用类的形式 多线程 使用concurrent.future并发模块,建立线程池,把future对象扔进去执行即可实现并发爬取效果 数据存储 使用Python ORM sqlalchemy保存到数据库,也可以使用自带的csv模块存在CSV中. API接口 因为API接口存在数据保护情况,一个电影的每一个分类只能抓取前25页,全部评论.好评.中评.差评所有分类能爬100页,每页有20个数据,即最多为

  • 浅谈Python接口对json串的处理方法

    最近学习Python接口测试,对于接口测试完全小白.大概一周的学习成果进行总结. 1.接口测试: 目前涉及到的只是对简单单一的接口进行参数传递,得到返回自. 2.关于各种概念: 2.1 http请求包含post方法.get方法.通过json串或XML传递,但后者未做研究 2.2 GET: 浏览器告诉服务器,只获取页面信息,并发送给我. 2.3 POST:浏览器告诉服务器想法不一些信息到某个网址,服务器需确保数据被存储且只存储一次. 2.4 HEAD:浏览器告诉服务器,给我消息头,像get那样被接

  • Python中Flask-RESTful编写API接口(小白入门)

    1.API接口:hello world 案例 from flask import Flask from flask_restful import Api, Resource app = Flask(__name__) api = Api(app) class HelloWorld(Resource): def get(self): return {'hello': 'world'} api.add_resource(HelloWorld, '/') if __name__ == '__main_

  • python调用API接口实现登陆短信验证

    API说明 调用地址:http://yzxyzm.market.alicloudapi.com/yzx/verifySms 请求方式:POST 返回类型:JSON 请求参数(Query) 名称 类型 是否必选 描述 phone STRING 必选 需要发送的手机号码 templateId STRING 必选 模板id,联系客服人员申请成功的模板ID variable STRING 可选 模板中变量参数名,参数值有多个时使用","隔开,例如"num:1234,money:888

  • python 接口返回的json字符串实例

    如下所示: JSON 函数 使用 JSON 函数需要导入 json 库:import json. 函数 描述 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON 字符串解码为 Python 对象 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib2 import urllib import cookielib import json def login(): data

  • 对Python实现简单的API接口实例讲解

    get方法 代码实现 # coding:utf-8 import json from urlparse import parse_qs from wsgiref.simple_server import make_server # 定义函数,参数是函数的两个参数,都是python本身定义的,默认就行了. def application(environ, start_response): # 定义文件请求的类型和当前请求成功的code start_response('200 OK', [('Con

  • Python利用Django如何写restful api接口详解

    前言 用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看://www.jb51.net/article/141661.htm 大量的数据保存到数据库比较方便.我用的pymsql,pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前在python3.x中,PyMySQL取代了MySQLdb. 1.连接数据库 # 连接数据库,需指定charset否则可能会报错 db = pym

  • 使用apiDoc实现python接口文档编写

    apiDoc的安装 npm install apidoc -g 点击官方文档 生成api的终端命令:apidoc -i 代码所在路径-o 生成文件的路径 接口文档的编写 文件的简介 project的介绍写在单独的json文件中apidoc.json: { "name": "project_name", "version": "0.1.0", "description": "who am i ,wh

  • python+requests+unittest API接口测试实例(详解)

    我在网上查找了下接口测试相关的资料,大都重点是以数据驱动的形式,将用例维护在文本或表格中,而没有说明怎么样去生成想要的用例, 问题: 测试接口时,比如参数a,b,c,我要先测a参数,有(不传,为空,整形,浮点,字符串,object,过短,超长,sql注入)这些情况,其中一种情况就是一条用例,同时要保证b,c的正确,确保a的测试不受b,c参数的错误影响 解决思路: 符合接口规范的参数可以手动去填写,或者准备在代码库中.那些不符合规范的参数(不传,为空,整形,浮点,字符串,object,过短,超长,

  • python 调用有道api接口的方法

    初学python ,研究了几天,写了一个python 调用 有道api接口程序 效果看下图: 申明:代码仅供和我一样的初学者学习交流 有道api申请地址http://fanyi.youdao.com/openapi?path=data-mode 申请很简单的 ps:审核不用花时间的,请勿滥用!! #-*- coding: UTF-8 -*- import urllib import urllib2 import requests import json import sys reload(sys

随机推荐