虽然接触Python蛮久了,但这算是第一次正儿八经做的项目,起源于实习过程中的一个需求,当时想着用Python还是Java,考虑到Pyhton对于测试人员接受度更高,于是决定用Python写这个项目,写完后也经过了两次优化,因此特来和大家分享。
一、项目介绍
Github 地址:yinyuscloor/AutoS3Tool: v1.0
主要用于AWS-S3的自动化/批量操作,绝对原创哦~
1、依据S3批量操作(批量下载、修改文件名、上传)需求,分析后采用Python的AWS 开发工具包—boto3进行工具的构建
2、设计三层框架,Base层存放基础的方法或工具(包括路径、S3基础操作、utils、Excel基础操作),BusinessScript层存放业务代码供使用 (businessS3:具体业务中S3的步骤方法,businessExcelCsv:具体业务中excel/csv的步骤方法),demandScript.py存放具体的业务。
3、Config.ini配置完基础信息后,该工具主要实现S3批量操作上传修改下载等操作,同时具备定制化需求(如下载+修改文件名+上传),具备可拓展性,易于推广使用!
①目录结构
②工具层面代码
工具层可能大家单独用得到,因此放上来。
baseS3Helper.py
import boto3
import re
import sys
from Base.utils import read_config_ini
from Base.basePath import BasePath
"""
Boto3 官方文档:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html
使用Python访问AWS S3
AWS配置,放在Config.ini文件里
boto3 不支持python3.6
"""
S3_FILE_CONF = read_config_ini(BasePath.CONFIG_FILE)['S3_FILE_CONF']
class S3Helper(object):
"""
需要下载boto3模块
"""
def __init__(self):
self.access_key = S3_FILE_CONF.get("ocr.lls.aws.s3.access-key")
self.secret_key = S3_FILE_CONF.get("ocr.lls.aws.s3.secret-key")
self.region_name = S3_FILE_CONF.get("ocr.lls.aws.s3.end-point")
self.bucket_name = S3_FILE_CONF.get("BUCKET_NAME")
self.url = S3_FILE_CONF.get("ENDPOINT_URL")
# 连接s3
self.s3 = boto3.resource(
service_name='s3',
aws_access_key_id=self.access_key,
aws_secret_access_key=self.secret_key,
endpoint_url=self.url,
)
self.client = boto3.client(
service_name='s3',
region_name=self.region_name,
aws_access_key_id=self.access_key,
aws_secret_access_key=self.secret_key,
)
def download_file_s3(self, bucket_name, file_name, local_file):
"""
从s3下载指定文件到本地
需要本地运行程序的目录下新建一个local_file完整目录
:param bucket_name: 桶名称
:param file_name: 要下载的文件,所在路径
:return: 下载完成返回True,下载出问题返回False,并打印错误
"""
bucket = self.s3.Bucket(bucket_name)
for obj in bucket.objects.all():
if obj.key == file_name:
p = re.compile(r'.*/(.*)')
result = p.search(file_name).group(1)
down_file = local_file + result
try:
bucket.download_file(file_name, down_file)
return True
except Exception as e:
print('出错了:' + str(e))
return False
def get_list_s3(self, bucket_name, file_name):
"""
用来列举出该目录下的所有文件
:param bucket_name: 桶名称
:param file_name: 要查询的文件夹
:return: 该目录下所有文件列表
"""
print("S3连接成功,开始获取【{}】目录下的文件".format(file_name))
# 用来存放文件列表
file_list = []
response = self.client.list_objects_v2(
Bucket=bucket_name,
Delimiter='/',
Prefix=file_name,
)
for file in response['Contents']:
s = str(file['Key'])
p = re.compile(r'.*/(.*)(\..*)')
if p.search(s):
s1 = p.search(s).group(1)
s2 = p.search(s).group(2)
result = s1 + s2
file_list.append(result)
return file_list
def upload_file_s3(self, file_name, bucket, s3_dir):
"""
上传本地文件到s3指定文件夹下
:param file_name: 本地文件路径
:param bucket: 桶名称
:param s3_dir:要上传到的s3文件夹名称
:return: 上传成功返回True,上传失败返回False,并打印错误
"""
res = sys.platform
p = re.compile(r'\w{1}')
s = p.search(res).group()
if s == 'w':
p = re.compile(r'.*\\(.*)(\..*)')
else:
p = re.compile(r'.*/(.*)(\..*)')
if p.search(file_name):
s1 = p.search(file_name).group(1)
s2 = p.search(file_name).group(2)
file = s1 + s2
s3_file = s3_dir + file
try:
self.s3.Object(bucket, s3_file).upload_file(file_name)
except Exception as e:
print('出错了:' + str(e))
return False
return True
baseExcel.py
import csv
from typing import Union, Any
from openpyxl.worksheet.worksheet import Worksheet
import openpyxl
"""
用于存放处理Excel和csv基础方法
"""
class BaseExcel(object):
def open_sheet_Excel(self, filepath, sheet_name_or_index) -> Union[str, Worksheet]:
'''打开表单-excel中某sheet'''
worksheets = openpyxl.load_workbook(filepath)
if isinstance(sheet_name_or_index, int): #若输入表单的序号
worksheet = worksheets._sheets[sheet_name_or_index]
elif isinstance(sheet_name_or_index, str): #若输入表单名
worksheet = worksheets[sheet_name_or_index]
else:
return "sheet输入有误,请输入sheet_name_or_index"
return worksheet
def read_header_Excel(self,filepath, sheet_name_or_index):
'''获取表单的表头'''
worksheet = self.open_sheet_Excel(filepath,sheet_name_or_index)
headers = []
for i in worksheet[1]:
headers.append(i.value)
return headers
def read_key_value_Excel(self,filepath,sheet_name_or_index):
'''
获取所有数据,且将表头中的内容与数据结合展示(以字典的形式)
如:[{'序号':1,'会员卡号': '680021685898','机场名称':'上海机场'},{'序号':2,'会员卡号': '680021685899','机场名称':'广州机场'}]
'''
worksheet = self.open_sheet_Excel(filepath,sheet_name_or_index)
rows = list(worksheet.rows)
# 获取标题
data = []
for row in rows[1:]:
rwo_data = []
for cell in row:
rwo_data.append(cell.value)
# 列表转换成字典,与表头里的内容使用zip函数进行打包
data_dict = dict(zip(self.read_header_Excel(filepath,sheet_name_or_index),rwo_data))
data.append(data_dict)
return data
@staticmethod
def write_change_Excel(filepath,sheet_name,row,column,data):
'''写入Excel数据'''
worksheets = openpyxl.load_workbook(filepath)
worksheet = worksheets[sheet_name]
# 修改单元格
worksheet.cell(row,column).value = data
# 保存
worksheets.save(filepath)
# 关闭
worksheets.close()
def csv_writer_csv(self,filepath):
'''csv_writer'''
#指定文件对象
f = open(filepath,"w",encoding="utf-8",newline="")
#基于稳健对象构建csv写入对象
csv_writer = csv.writer(f)
return csv_writer
二、环境依赖
1、Pycharm或其他编译器
2、python版本: python >= 3.7
3、boto3==1.24.85
boto3 是 python 中实现连接 S3 的库/软件包,可以拿来直接调用操作 S3(下载、上传等等); 此外 boto3 只支持 python3.7 及以上版本,建议安装高一些的 python 版本。
4、openpyxl==3.0.10
openpyxl是读写 xlsx/xlsm/xltx/xltm 的 Python 库,简单易用,功能广泛,本项目应用openpyxl来处理xlsx文件
5、部署:pip install -r requirement.txt 或其他形式装库皆可
总结
大家如果有疑问都可以评论提出,有不足之处请大家批评指正,希望能多结识这方面的朋友,共同学习、共同进步。