本篇内容介绍了“Python获取接口请求耗时的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
举例代码:
import socket import time def funcRunTimes(func): def wrapper(*args): startTime = time.time() result = func(*args) endTime = time.time() execTime = endTime - startTime return (result,execTime) return wrapper @funcRunTimes def shakeHands(hosts,port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((hosts, port)) return s except Exception as e: print(e) return None @funcRunTimes def websiteResponseTime(fd,methods,url): sendMsgs = "%s %s HTTP/1.1 Host: 127.0.0.1:8080 " %(methods,url) fd.send(sendMsgs.encode()) recv_data = "" while True: recv_data = str(fd.recv(15)) break httpCode = recv_data.split(" ")[1] return httpCode def main(): hosts = "www.juejin.cn" port = 80 methods = "GET" url = "/" print("执行命令为: %s %s:%d %s " % (methods, hosts, port, url)) shakeInfo = shakeHands(hosts,port) if shakeInfo == None: print("errors") return responseInfo = websiteResponseTime(shakeInfo[0],methods,url) print("接口状态码为:" , responseInfo[0],"握手耗时: %.6fs" %(shakeInfo[1]) , "请求接口耗时: %.6fs" %(responseInfo[1]) ,"总共耗时为: %.6fs" % (shakeInfo[1] + responseInfo[1])) if __name__ == '__main__': main()
项目中使用了
python装饰器,若还对
python装饰器不太了解的小伙伴,可以参考一下下面这篇文章:python | 探寻python装饰器
项目展示
打开项目,修改
hosts、
port、
methods以及
url的变量,即可运行
python程序便可获得该页面的详细信息的时间,其中包括
TCP/IP三次握手时间 以及 请求接口耗时,最后是 总的耗时,
如何获得握手时间
在获取握手时间的时候,不能使用
http库,例如:
requests,因为它默认会进行
tcp/ip三次握手,而后再进行资源请求,所以我们要使用
socket来做这个需求。
在
python中,
socket提供了一种跨平台的网络通信接口,可以用它来创建各种类型的网络连接。
例如代码如下:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 8080))
在上面的代码中,我们先导入
socket库,而后使用
socket.socket()创建一个
socket句柄,而中间的参数分别代表的意思为:
socket.AF_INET: 指定
IPv4协议。
socket.SOCK_STREAM: 指定使用
TCP流式套接字类型。
而
s.connect则开始连接服务器,其参数类型为元组类型,参数值为远程主机名 和 远程端口。
如上代码,当远程服务器连不上的时候或者其他异常的时候,该代码会抛异常,若没有异常,则证明端口通的。
我们仅需要在此之前和之后,都拉一下当前时间戳,就可以计算出握手所耗费的时间,例如:
import socket import time try: startTime = time.time() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 8080)) endTime = time.time() print("runtimes: " , endTime-startTime) except Exception as e: print("捕获异常" , e)
若没有抛错,我们即可获得握手时间。
如何获得请求时间
握手成功后,我们就可以向该服务器发送
http报文了,注意最简单报文的格式是:
请求方法 请求路由 版本号
请求头(主机名)
空行
例如:
GET / HTTP/1.1
Host: 127.0.0.1:8080
如果我们不添加
Host请求头,则会抛错:
HTTP/1.1 400 Bad Request: missing required Host header。
在
python中,我们直接使用
s.send()函数即可发送请求,例如:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 8080)) s.send(b"GET / HTTP/1.1 Host: 127.0.0.1:8080 ")
上述代码中,
是换行的意思,也称之为
CRLF,注意最后的2个
是有一个空行,来标志
http请求头的结束。
一般来说,我们请求接口后,会读取服务器返回来的状态码,以便开发验证是否是成功的。
这里可以使用
s.recv()函数来读取服务器传回来的信息,例如读取从服务器返回的15个字节
s.recv(15)。
我们可以参考计算握手时间的方法,来计算一下资源请求的时间,代码如下:
import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 8080)) startTime = time.time() s.send(b"GET / HTTP/1.1 Host: 127.0.0.1:8080 ") recv_data = str(s.recv(15)) endTime = time.time() print("runtimes: ", endTime - startTime,"接口返回状态码: " , recv_data.split(" ")[1])
如果远程主机和远程端口都正常的话,我们大概会得到如下的信息:
善用装饰器
我们计算握手时间,和计算资源请求时间,都是相同的代码,因为计算的功能不同,所以我们需要被迫写2次,这个时候,就可以使用装饰器,来把这个额外非核心功能给抽离出来,而将计算握手和计算资源请求都给封装为函数,而后通过函数来调用装饰器,就可以获取2种请求时间了。
我们先将装饰器抽离出来:
def funcRunTimes(func): def wrapper(*args): startTime = time.time() result = func(*args) endTime = time.time() execTime = endTime - startTime return (result,execTime) return wrapper
我们在
funcRunTimes中直接返回
wrapper函数,而在
wrapper函数中,定义开始时间和结束时间,在二者的中间执行函数
func,最后将
func的结果以及函数执行的时间封装为一个元组进行返回。
此时,我们可以封装函数了,例如我们想获取握手的时间,我们可以这样写:
@funcRunTimes def shakeHands(hosts,port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((hosts, port)) return s except Exception as e: print(e) return None
如果该远程主机可以连上,我们直接返回
socket句柄,若连接不上,直接打印错误,返回
None。
调用该函数的是,我们接收返回值即可:
shakeInfo = shakeHands(hosts,port)
注意,
shakeInfo是一个元组,有2个元组,第一个是
socket句柄,第二个是执行该函数所需要的时间。
我们再将资源请求函数封装一下,就可以完成这个项目了。