接口理解和Python实现

接口

1、什么是接口?
  接口一般来讲分为两种:

(1)程序内部的接口:方法与方法、模块与模块之间的交互,程序内部抛出的接口,如登录发帖,发帖就必须要登录,如果不登录不能发帖,发帖和登录这两个模块之间就要有交互,就会抛出一个接口,进行内部系统调用。

(2)系统对外的接口:从别人的网站或服务器上获取资源或信息,对方不会提供数据库共享,只能提供一个写好的方法来获取数据,如购物网站和第三方支付之间,购物网站支付时可选择第三方支付方法,但第三方不会提供自己的数据库给购物网站,只会提供一个接口,供购物网站进行调用。

2、接口的分类?

接口分类一般分为两种:

(1)webService接口:走soap协议通过http传输,请求报文和返回报文都是xml格式的。测试时需要通过工具才能进行调用、测试。少数公司还在使用这种接口,如医院等行业。

(2)http api接口:走http协议,通过路径来区分调用的方法,请求和报文都是key-value形式的,返回报文一般都是json串,有get和post等方法。目前来讲,是最常用的。

3、接口返回数据

接口返回的数据一般都是json串,json是一种通用的数据类型,格式为key-value。

Requests库

requests.get()

get一般用于获取,查询数据,不会修改服务器数据。由于它是读取的,故可对读取数据进行缓存。

r = requests.get(url, params)
  1. 返回值为response对象。
  2. url为查询对象所在服务器地址,params即查询的限制条件,为字典形式。若params为空则不添加限制。
  3. 由于字典中键值一一对应,有时会出现url有多个参数的情况,此时可以将值写成列表的形式。
  4. 在浏览器中,get的url长度一般都有限制,因为其缓存的特性,过长的url容易导致内存爆炸。

requests.post()

post将某些数据发送到服务器时使用,可以向服务器发送修改请求,进行数据的修改,但是不可进行缓存。

requests.post(url, data)
  1. 返回值为response对象
  2. 浏览器中,post请求分为请求头(header)和请求体(body)
  3. data为请求的内容,一般是字典,元组列表,字节或要发送到指定URL的文件对象;如果是json的格式,最好使用json.dumps,反序列化一下,避免格式错误,如果是其他格式,就都是字符串了

response

  • r.content:返回网页的HTML内容,直接从网络上面抓取的数据,没有经过任何解码,是编码后的byte类型(str数据类型)。

  • r.text:返回网页的HTML内容,是unicode类型(二进制)。是 requests将 response.content进行解码的字符串,解码需要指定一个编码方式,requests会根据自己的猜测来判断编码的方式,有时候可能会猜测错误,导致解码产生乱码。

  • r.json:返回网页的HTML内容,但是把返回响应的json字符串转换成字典。 response.json() 等同于 json.loads(response.text);返回信息的格式是json对象;若r不是json格式则会导致返回报错,从而可判断是开发的接口出错了。

  • r.status_code:返回 http 的状态码,200是成功,404是未找到接口路径,500是服务器错误等等

  • r.url:返回请求时的url地址

  • r.headers:返回服务器给你的响应header

  • r.cookies:返回服务器给你的cookies

  • r.encoding:可以用来定义编码(如utf-8),如果编码不对,网页就会乱码的。

请求头和请求体

1. 请求行
	请求方式 请求url 请求协议/版本
	GET /login.html	HTTP/1.1

	* 请求方式:
		* HTTP协议有7中请求方式,常用的有2种
			* GET:
				1. 请求参数在请求行中,在url后。
				2. 请求的url长度有限制的
				3. 不太安全,因为所发送的数据是 URL 的一部分,在发送密码或其他敏感信息时绝不要使用 GET 

			* POST:
				1. 请求参数在请求体中
				2. 请求的url长度没有限制的
				3. 相对安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

2. 请求头:客户端浏览器告诉服务器一些信息
	请求头名称: 请求头值
	* 常见的请求头:
		1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
			* 可以在服务器端获取该头的信息,解决浏览器的兼容性问题

		2. Referer:http://localhost/login.html
			* 告诉服务器,我(当前请求)从哪里来?
				* 作用:
					1. 防盗链
					2. 统计工作

3. 请求空行
	空行,就是用于分割POST请求的请求头,和请求体的。
	
4. 请求体(正文):
	* 封装POST请求消息的请求参数的,GET没有请求体

在请求网页爬取的时候,输出的text信息中会出现抱歉,无法访问等字眼,这就是禁止爬取,需要通过反爬机制去解决这个问题。
headers是解决requests请求反爬的方法之一,相当于我们进去这个网页的服务器本身,假装自己本身在爬取数据。对反爬虫网页,可以设置一些headers信息,模拟成浏览器取访问网站 。

JSON

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。通常用于在 Web 客户端(浏览器)与 Web 服务器端之间传递数据。

JSON 的语法规则

  • 数组(Array)用方括号[ ]表示。
  • 对象(Object)用大括号{ }表示。

名称/值对(name/value)组合成数组和对象。名称(name)置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组,并列的数据之间用逗号分隔。

requests其它方法

  • requests.put(url):从客户端向服务器传送的数据取代指定的文档的内容。
  • requests.delete(url): 请求服务器删除指定的页面。
  • requests.head(url): 只请求页面的头信息。

Flask

https://blog.csdn.net/qq_44864833/article/details/122423539

装饰器

  • @ 符号就是装饰器的语法糖。它放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上,和这个函数绑定在一起。在我们调用这个函数的时候,第一件事并不是执行这个函数,而是将这个函数做为参数传入它头顶上这顶帽子,这顶帽子我们称之为装饰函数 或 装饰器。
  • 装饰器通过闭包实现,装饰器作为外函数传入目标函数,内函数执行具体操作。
  • 不带参数的装饰器:
def decorate(func):     # 这里的参数是函数
   print("装饰器执行了")      # 可以看出,这里的装饰器就是外函数有了参数的闭包
   def inner():
       print("执行函数了")
       func()
       print("函数执行结束了")

   return inner;


@decorate      # @decorate 值得是装饰器语法糖,它的执行意义是 comment = decorate(comment)  comment()
def comment():
   print("评论开始了")
   
comment()

  • 带参数的装饰器:
def decorate (func):
    def inner(a,b):     # 这里的inner函数有参数,则也需要func也需要有参数
        print("努力计算中!!!")
        func(a,b)
    return inner


@decorate  # 这里本质是 f = decorate(add1), f(a,b) 所以inner函数也需要和add1函数有相同的形参列表
def add1(a,b):    
    print("%d + %d = %d"%(a,b,a+b))
    
add1(2,3)
# 输出: 努力计算中!!!
# 2 + 3 = 5

@app.route()

在这里插入图片描述

  • @app.route(‘URL’)的功能,就是程序运行起来,然后输入这里的URL,页面上显示函数的return值。
  • 注意:@app.route只指定内部路由寻址方向,即’/test1/'前面的内容它不会涉及。其中127.0.0.1是服务器IP,如果不指定就是本机IP,冒号后面的5000是端口号。服务器IP和端口号决定函数在哪里运行。
  • 建议: 尽量保持route()内的URL和被修饰的函数名相同,这样就可以大大避免在同一文件中因函数名字相同而导致程序报错。(这里URL和被修饰的函数名无本质联系,这里的建议只是一种编码习惯)
  • @app.route()可传输参数:https://blog.csdn.net/qq_33962481/article/details/113522479

app.run()

  1. 指定访问的网站地址的方法: (加入host的参数指定当前机器的ip)
    app.run(host=“192.168.1.109”,debug=True)

  2. 如果机器存在多个网卡或代码放到另外一台机器,让他智能识别(直接输入当前及其的ip即可)
    app.run(host=“0.0.0.0”,debug=True)

  3. 修改访问的端口号的方法:(加入port的参数指定端口)
    app.run(host=“192.168.1.109”,debug=True, port=81)

request模块——都是用来获取提交的内容

  • request.method():返回请求方法
  • request.Form:获取以POST方式 提交的数据(接收Form提交来的数据);
  • request.args:获取地址栏参数(不分提交方式,一般默认GET);当浏览器以post方式请求时,若请求地址栏也有参数也可以通过request.args.get(键) 方式获取
  • request:包含以上两种方式(优先获取GET方式提交的数据)
  • request.json:只能够接受方法为POST、Body为raw,header 内容为 application/json类型的数据。执行步骤是首先判断Content-Type是不是application/json,如果是,做json.load;如果不是,直接返回None。
  • json.loads(request.data) 能够同时接受方法为POST、Body为 raw类型的 Text 或者 application/json类型的值

理解发送数据和接受数据

  • 使用requests库的post方法,就是在把data推进url对应的服务器中(先传再收)
  • 使用@app.route,request模块就是在接收传进来的数据,后面可以根据相应的内容,提供对应的返回数据(先收再传)

例子

接收:

app = Flask(__name__)

#获取状态数据接口,http://192.168.1.109:80/getState
@app.route("/getState",methods=['POST'])
def getState():
    msg = []
    try:
        if request.method == 'POST':
            msg = [{'tag': 'M1', 'state': '1'}, 
                   {'tag': 'M2', 'state': '0'}]
        #0 正常,1 异常
    except:
        msg = []
    return json.dumps(msg,ensure_ascii=False)

if __name__ == '__main__':
    app.run(host = '0.0.0.0', port = 80)

发送:

url = 'http://192.168.1.109:80/getState'
#无需输入
data = {}
r = requests.post(url,data = data)
print(r.json())
  • 这里的例子中,post时无需输入数据;
  • 如果有特定需求,比如想获得某个指标的状态,可以在第一段中添加
paras = request.form.to_dict()
# 或paras = request.get_json(), 根据不同的信息格式而定

然后读取paras中的信息,根据信息要求返回相应的内容;

  • 第二段中也要给data添加相应的内容,如指标的名字之类的信息,要注意data的格式需和第一段代码的要求保持一致。

实践报错整理

OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。

解决方法:

  • 命令提示符中查看哪个进程占用了端口号
    netstat -ano|findstr 3306
    findstr 3948
    (查看详细信息,5272为上一步查出来的pid结果)
  • kill进程(注意用管理员权限打开,要不然关不了)
    taskkill /pid 3948 /F
  1. WARNING: This is a development server. Do not use it in a production deployment.
    分析与解决:

方法一:
from gevent import pywsgi
if name == ‘main’:
server = pywsgi.WSGIServer((‘0.0.0.0’, 5000), app)
server.serve_forever()

方法二:
from wsgiref.simple_server import make_server
if name == ‘main’:
server = make_server(‘’, 5000, app)
server.serve_forever()
from flask_script import Manager

方法三:
from flask_script import Manager
manager=Manager(app)
if name == “main”:
db.create_all()
app.run(debug=False) #开发者模式
manager.run() #非开发者模式

ValueError: too many values to unpack (expected 2)

使用requests.post时出现,data格式是列表,元素为字典

  1. 第一步:data = json.dumps(data)
    原因:数据是json格式,需要json.dumps()反格式化
  2. 报错:TypeError: Object of type date is not JSON serializable
    第二步:
class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        # 处理返回数据中有date类型的数据
        if isinstance(obj, datetime.date):
            return obj.strftime("%Y-%m-%d")
        # 处理返回数据中有datetime类型的数据
        elif isinstance(obj, datetime.datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        # 处理返回数据中有decimal类型的数据
        elif isinstance(obj, decimal.Decimal):
            return float(obj)
        else:
            return json.JSONEncoder.default(self, obj)
            
data = json.dumps(data, ensure_ascii=False, cls=DateEncoder).encode("utf-8")

原因:日期类型的数据存在,json.dups()无法处理,要转成字符串
3. 报错:“requests.exceptions.InvalidSchema: No connection adapters were found for…
第三步:url的地址没加http://,地址不完整导致访问出错

requests.exceptions.ConnectionError: HTTPConnectionPool(host=‘****, port=80): Max retries exceeded

连接次数太多了,所以避免使用延时连接(也有可能url之类的写错了,记得检查)
解决方法(两种):

  1. 在headers里面加:{‘connection’: ‘close’}
  2. requests.adapters.DEFAULT_RETRIES = 8

跳板机

跳板机(Jump Server),也称堡垒机,是一类可作为跳板批量操作远程设备的网络设备,是系统管理员或运维人员常用的操作平台之一。

跳板机是网络中容易受到侵害的主机,所以跳板机也必须是自身保护完善的主机。通常至少配备两块网卡设备,分别具备不同的网络连接。 一个连接外网,用以对目标服务器的远程登录及维护;另一个则连接内网,便于内部网络的管理、控制和保护,通过网关服务提供从私网到公网,或从公网到私网的特殊协议路由服务。

在这里插入图片描述
当需要用本地电脑远程连接服务器(或其它电脑)时,很有可能出现两个设备存在网络限制,彼此无法互联,所以可以通过跳板机这个中介,分别连接到两个设备,从而实现远程连接的目的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值