背景和目的:
利用python request 编写脚本测试公司系统的文件上传接口。前端读取文件的大小然后文件分片传给后端,后端将每一片数据重新组合成文件。大概的过程是:前端将整个文件的md5、size(大小)、name(文件名)、ext(文件后缀)、totalchunk(分片总数)与分片文件的md5、chunk(分片数据),chunkindex(当前分片文件的下标)等传给后台,后台取得这些数据后,通过chunkindex将每一片数据重组,重组完后,进行md5校验,判断文件上传是否成功。我只需要去调用后台的接口,然后判断文件是否上传成功,并且上传没有错误,其他的文件校验就不用去深究。
开发前端使用的是vue,后台使用的是php,要利用python实现对这一接口的调用,那么就先要将前端数据给模拟出来,然后循环去调用接口,将文件分片上传,我的思路大概如下:
1.获取整个文件的大小、名字、后缀、分片总数,定义每片文件的大小:
1 2 3 4 5 6 7 8 | def __init__( self ,data): dat = json.loads(data) self .path = dat[ 'path' ] # 获取文件路径 self .CHUNK_SIZE = 1024 * 1024 * 2 # 定义每片文件的大小 self .size = os.path.getsize(dat[ 'path' ]) # 获取文件的大小 self .totalchunk = math.ceil( self .size / self .CHUNK_SIZE) # 获取文件的分片总数 self .ext = os.path.basename(dat[ 'path' ]).split( '.' ).pop() # 获取文件的后缀 self .name = os.path.basename(dat[ 'path' ]) # 获取文件的名字 |
2.获取文件的md5,查看了开发那边的md5算法,利用python实现过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # 使用hashlib库的md5方法获取指定文件的md5 def getmd5( self ,path): m = hashlib.md5() with open (path, 'rb' ) as f: for line in f: m.update(line) md5code = m.hexdigest() return md5code # 开发那边对md5的算法进行了优化,当文件的大小小于1M时,直接通过getmd5方法去获取文件的md5值; # 当文件大于1M时,通过截取整个文件中的某几个片段,然后拼接成一个文件,再去获取其md5值,最后删除这个文件 def md5( self ,path): if self .size < 1024 * 1024 : return self .getmd5(path) f = open (path, 'rb' ) f.seek( 0 , 0 ) data = f.read( 2012 ) f.seek( int ( self .size / 2 ) - 1999 , 0 ) data + = f.read( 1999 ) f.seek( - 2010 , 2 ) data + = f.read( 2010 ) f.close() path = 'D:/copy_' + str (os.path.basename(path)) f = open (path, 'wb' ) f.write(data) f.close() val = self .getmd5(path) os.remove(path) return val |
3.调用文件上传的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | def uploading( self , chunkIndex): MD5 = self .md5( self .path) # 整个文件的md5 start = (chunkIndex - 1 ) * self .CHUNK_SIZE # 截取文件的起始位置 end = min ( self .size, start + self .CHUNK_SIZE) # 截取文件的结束位置 f = open ( self .path, 'rb' ) f.seek(start) data = f.read(end) # 待分片上传的数据 f.close() path1 = 'D:/copy_' + str (os.path.basename( self .path)) # 将该数据保存在本地 f = open (path1, 'wb' ) f.write(data) f.close() chunk_md5 = self .md5(path1) # 读取分片上传数据的md5 # 将所有的数据储存在files字典当中,利用requests的files传输数据 # 使用requests files类型时,要像下面一样构建参数,不然会有错误 files = { 'chunk' :( 'blob' ,data, 'application/octet-stream' ), 'name' :( None , self .name), 'ext' :( None , self .ext), 'index' :( None ,chunkIndex), 'total' : ( None , self .totalchunk), 'size' : ( None , self .size), 'chunk_md5' : ( None ,chunk_md5), 'md5' : ( None ,MD5), } # 使用requests发送接口请求 res = self .request.send( 'post' , 'https://10.104.17.222/bank/elements/uploading' , verify = False , files = files) os.remove(path1) # 删除存在本地的分片文件 return res.json() |
4.循环调用文件上传的接口
1 2 3 4 | chunkIndex = 1 while chunkIndex < = totalchunk: res2 = upload.uploading(chunkIndex) chunkIndex + = 1 |
5.从服务器上去读取通过接口上传的文件的md5值,判断是否正确
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】