18.4 操作 excel 文件
Python 中一般使用 xlrd 庫來讀取 Excel 文件, xlrd 庫是 Python 的第三方庫。
18.4.1 xlrd 庫安裝
Xlrd 庫跟其他第三方庫一樣,都是通過 pip install xlrd 命令來安裝。
安裝成功之后,在 C:\Python34\Lib\site-packages 下可以看到相應的Xlrd 庫目錄。
以下是xlrd 庫下的相應模塊方法
備注:喜歡研究的同學,可以去研究 xlrd 庫下的相應模塊的實現原理。
18.4.2 在 Python3 下打開excel文件,獲取一個Book()對象
例如:讀取 result.xls 的數據。
程序實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
result_file =xlrd.open_workbook("./result.xls")
18.4.3 獲取 sheets 數目
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("./result.xls")
print(file.nsheets)
運行結果:
18.4.4 獲取 sheets 列表
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("./result.xls")
print(file.sheets())
運行結果:
18.4.5 獲取 sheets name 列表
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("./result.xls")
print(file.sheet_names())
運行結果:
18.4.6 獲取文件中的 Sheet
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("./result.xls")
print(file.sheets())
sheet1 = file.sheets()[0] #sheets返回一個sheet列表
sheet2 = file.sheet_by_index(0) #通過索引順序獲取
sheet3 = file.sheet_by_name('保單查詢結果清單') #通過名稱獲取
18.4.7 獲取行數,列數
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("result.xls")
# 獲取當前文件的表
shxrange = range(file.nsheets)
try:
sh = file.sheet_by_name("保單查詢結果清單")
except:
print("no sheet in %s named '保單查詢結果清單'",format("result.xls"))
# 獲取行數
nrows =sh.nrows
# 獲取列數
ncols = sh.ncols
#打印表格的行數和列數
print("nrows{0},ncols{1}".format(nrows,ncols))
運行結果:
18.4.8 獲取某行,某行值列表,某列,某列值列表
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("result.xls")
# 獲取當前文件的表
shxrange = range(file.nsheets)
try:
sh = file.sheet_by_name("保單查詢結果清單")
print(sh)
except:
print("no sheet in %s named '保單查詢結果清單'",format("result.xls"))
#獲取第一行
print(sh.row(1))
#獲取第一行值列表
print(sh.row_values(1))
#獲取第一列
print(sh.col(1))
#獲取第一列值列表
print(sh.col_values(1))
運行結果:
18.4.9 獲取單元格的值
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("result.xls")
# 獲取當前文件的表
shxrange = range(file.nsheets)
try:
sh = file.sheet_by_name("保單查詢結果清單")
print(sh)
except:
print("no sheet in %s named '保單查詢結果清單'",format("result.xls"))
#獲取單元格的值
cell = sh.cell(1,1)
print(cell)
cell_value1 = sh.cell_value(1,1)
print(cell_value1)
cell_value2 = sh.cell(1,1).value
print(cell_value2)
運行結果:
注意:用xlrd讀取excel是不能對其進行操作的:xlrd.open_workbook()方法返回xlrd.Book類型,是只讀的,不能對其進行操作。
18.4.10 讀取 Excel 應用案例
案例1:獲取result.xls文件下的保單查詢結果清單表數據
代碼實現:
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("result.xls")
# 獲取當前文件的表
shxrange = range(file.nsheets)
try:
sh = file.sheet_by_name("保單查詢結果清單")
except:
print("no sheet in %s named '保單查詢結果清單'",format("result.xls"))
# 獲取行數
nrows =sh.nrows
# 獲取列數
ncols = sh.ncols
#打印表格的行數和列數
print("nrows{0},ncols{1}".format(nrows,ncols))
#獲取第二行第一列數據(第一行是標題)
cell_value = sh.cell_value(1,0)
print(cell_value)
# 新建一個空的列表
row_list =[]
for i in range(0,nrows):
row_data =sh.row_values(i)
row_list.append(row_data)
# 輸出數據
print(row_list)
運行結果:
案例2:xlrd讀取Excel中的日期。
#導入 xlrd 庫
import xlrd
# 打開 Excel 讀取文件,open_workbook()為打開 Excel文件的方法,參數為:文件名
file =xlrd.open_workbook("./result.xls")
# 獲取當前文件的表
shxrange = range(file.nsheets)
try:
sh = file.sheet_by_name("保單查詢結果清單")
except:
print("no sheet in %s named '保單查詢結果清單'",format("result.xls"))
#獲取單元格的值
cell = sh.cell(2,5)
print(cell)
cell_value1 = sh.cell_value(2,5)
print(cell_value1)
運行結果:
18.4.11 xlwt 庫安裝
Xlrd 庫只讀,如果想新建一個test.xls文件,就需要安裝 xlwt 庫,跟其他第三方庫一樣,都是通過 pip install xlwt 命令來安裝。
安裝成功之后,在 C:\Python34\Lib\site-packages 下可以看到相應的 xlwt 庫目錄。
18.4.12 創建一個Excel文件並創建一個Sheet
程序實現:
from xlwt import *
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
book.save('myExcel.xls')
運行結果:
Workbook 類可以有 encoding 和 style_compression 參數。
【encoding】:設置字符編碼,
【style_compression】:表示是否壓縮。
這樣設置:w = Workbook(encoding='utf-8'),就可以在excel中輸出中文了。默認是ascii。
18.4.13 向sheet寫入內容
格式:sheet.write(r, c, label="", style=Style.default_style)
(1)簡單寫入。
程序實現:
from xlwt import *
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
# 在sheet1 中簡單插入內容
sheet.write(0, 0, label = 'Row 0, Column 0 Value')
# 保存內容
book.save('test1.xls')
運行結果:
(2)設置格式寫入。
代碼實現:
from xlwt import *
import xlwt
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
# 設置格式
font = xlwt.Font() # 字體
font.name = 'Times New Roman'
font.bold = True
font.underline = True
font.italic = True
style = xlwt.XFStyle() # 創建一個格式
style.font = font # 設置格式字體
# 在sheet1 中插入格式化的內容
sheet.write(1, 0, label = 'Formatted value', style) # Apply the Style to the Cell
# 保存內容
book.save('test2.xls')
備注:這個例子,需要運行的機器有對應的字體。
(3)寫入日期。
程序實現:
from xlwt import *
import xlwt
import time
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
style = xlwt.XFStyle()
#寫入當前時間
time = time.strftime("%Y%m%d%H%M%S", time.localtime())
style.num_format_str = 'M/D/YY' # Other options: D-MMM-YY, D-MMM, MMM-YY, h:mm, h:mm:ss, h:mm, h:mm:ss, M/D/YY h:mm, mm:ss, [h]:mm:ss, mm:ss.0
sheet.write(0, 0, time, style)
# 保存內容
book.save('test3.xls')
運行結果:
(4)寫入公式。
程序實現:
from xlwt import *
import xlwt
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
#寫入公式
sheet.write(0, 0, 5) # Outputs 5
sheet.write(0, 1, 2) # Outputs 2
sheet.write(1, 0, xlwt.Formula('A1*B1')) # 輸出 "10" (A1[5] * A2[2])
sheet.write(1, 1, xlwt.Formula('SUM(A1,B1)')) # 輸出 "7" (A1[5] + A2[2])
# 保存內容
book.save('test4.xls')
運行結果:
(5)寫入鏈接。
程序實現:
from xlwt import *
import xlwt
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
#寫入鏈接
sheet.write(0, 0, xlwt.Formula('HYPERLINK("http://www.google.com";"Google")')) #輸出 "Google"鏈接到http://www.google.com
# 保存內容
book.save('test5.xls')
運行結果:
18.4.14 xlutils 庫安裝
如果想修改一個test.xls文件內容,就需要安裝 xlutils 庫,跟其他第三方庫一樣,也是通過 pip install xlutils 命令來安裝。
安裝成功之后,在 C:\Python34\Lib\site-packages 下可以看到相應的 xlutils 庫目錄。
18.4.15 修改Excel表內容
原理:復制一個 xlrd.Book 對象,生成一個 xlwt.Workbook 對象,可以對 xlwt.Workbook 進行修改。
例子:
第一步:先新建一個test1.xls文件,在里面寫入4條數據。
程序實現:
from xlwt import *
from xlrd import open_workbook
from xlutils.copy import copy
#新建一個 test1.xls 的文件,並在新建的文件里寫入內容。
book = Workbook(encoding='utf-8')
sheet = book.add_sheet('Sheet1')
sheet.write(0, 0, label = 'name')
sheet.write(0, 1, label = 'age')
sheet.write(1, 0, label = 'xiao')
sheet.write(1, 1, label = '18')
book.save('test1.xls')
運行結果:
第二步:修改test1.xls文件內容。
程序實現:
from xlwt import *
from xlrd import open_workbook
from xlutils.copy import copy
#第二步:打開文件,修改文件內容
book = open_workbook('test1.xls')
wb = copy(book) #wb即為xlwt.WorkBook對象
ws = wb.get_sheet(0) #通過get_sheet()獲取的sheet有write()方法
ws.write(1, 0, '張三')
ws.write(1, 1, '28')
wb.save('test1.xls')
運行結果:
18.4.16 Python3下接口數據驅動之Excel案例
教育局招生管理系統登錄接口用例參數化實現步驟:
(一)編寫完整的接口測試用例
1、打開抓包工具:fiddler。
2、登錄教育局招生管理系統。
3、抓取登錄http請求。
4、分析登錄http請求(請求地址、是否重定向、get請求還是post請求、請求的頭信息、請求的response)。
5、數據的處理(處理抓取到的頭信息)
6、編寫接口代碼。
7、接口測試結果斷言驗證。
第一步:下面對fiddler抓取到的數據進行分析。
【請求方法】:帶參數的get
【請求地址】:http://127.0.0.1:8090/recruit.students/login/in?account=admin&pwd=660B8D2D5359FF6F94F8D3345698F88C
【請求頭信息】:
Host: 127.0.0.1:8090
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1:8090/recruit.students/login/view
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=AED5BBB1B5E4F9BEDCC3A0FC88668871; userInfoCookie=""
【請求的response】:空
請求的 response 為空是因為登錄的時候,做了跳轉,狀態碼為:302,跳轉到了
http://127.0.0.1:8090/recruit.students/school/manage/index 這個地址,這個狀態碼為200。
查看http://127.0.0.1:8090/recruit.students/school/manage/index 這個地址請求的response,返回的是登陸后的信息。
通過分析,我們是清楚的了解到這個接口的情況。
第二步:接着還需要請求頭信息的處理,去掉一些沒用的請求頭信息,保留如下:
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Referer": "http://127.0.0.1:8090/recruit.students/login/view",
【Connection】:如果只是測試登錄接口,這個參數可以去掉,如果需要測試登錄之后新建學校,那這個頭信息就需要保留。
【User-Agent】:模擬用戶利用瀏覽器訪問Web網站的真實行為,每個接口都需要。
【Referer】:登錄重定向的時候用到。
第三步:最后編寫代碼實現。
程序實現:
import requests
url="http://127.0.0.1:8090/recruit.students/login/in?"
#把請求頭信息進行處理,去掉一些沒用的,保留一些有用頭信息·
headers = {
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Referer": "http://127.0.0.1:8090/recruit.students/login/view",
}
# URL參數
payload = {'account': 'admin','pwd':'660B8D2D5359FF6F94F8D3345698F88C'}
# 發送Post請求
response = requests.post(url,headers = headers,data=payload)
# 查看響應內容,response.text 返回的是Unicode格式的數據
print(response.text)
# 查看響應碼
print(response.status_code)
(二)新建一個data.xls文件,組織測試用例參數。
(三)編寫一個readExcel方法。
程序實現:
import requests
import xlrd
def readExcel(rowx, filePath='data.xls'):
'''
讀取excel中數據並且返回
:parameter filePath:xlsx文件名稱
:parameter rowx:在excel中的行數
'''
book = xlrd.open_workbook(filePath)
sheet = book.sheet_by_index(0)
return sheet.row_values(rowx)
#提取第一個測試用例數據
print("第一行數據內容:",readExcel(2))
#查看數據的類型
print("數據類型:{0}:".format(type(readExcel(2))))
# 從列表中提取url
url = readExcel(2)[3]
print(url)
# 從列表中提取data參數
data = readExcel(2)[4]
print(data)
運行結果:
(四)測試用例數據參數化。
完整程序:
import requests
from bs4 import BeautifulSoup
import xlrd
import json
def readExcel(rowx, filePath='data.xls'):
'''
讀取excel中數據並且返回
:parameter filePath:xlsx文件名稱
:parameter rowx:在excel中的行數
'''
book = xlrd.open_workbook(filePath)
sheet = book.sheet_by_index(0)
return sheet.row_values(rowx)
#提取第一個測試用例數據
print("第一行數據內容:",readExcel(2))
#查看數據的類型
print("數據類型:{0}:".format(type(readExcel(2))))
# 從列表中提取url
url = readExcel(2)[3]
print(url)
# 從列表中提取data參數
# 由於JSON中,標准語法中,不支持單引號,屬性或者屬性值,都必須是雙引號括起來,用字符串方法replace("'",'\"')進行處理
data1 =readExcel(2)[4].replace("'",'\"')
#因為請求參數數據類型是字典,所以進行了反序列化的處理。
data = json.loads(data1)
print(data)
print(type(data))
print("---------------------------------------------")
#招生系統接口例子
headers = {
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Referer": "http://127.0.0.1:8090/recruit.students/login/view",
}
# URL參數
payload = data
# 發送get請求
response = requests.get(url,headers = headers,params=payload)
# 打印請求response后的URL
print(response.url)
# 查看響應內容,response.text 返回的是Unicode格式的數據
print(response.text)
# 查看響應碼
print(response.status_code)運行結果:
運行結果:
提取Excel表數據注意的幾點:
1、需要明確提取excel 表中那個sheet的數據。
2、一個測試用例按行去提取。
3、從Excel表提取的行數據,是一個列表,列表的元素是字符串,如果接口參數類型如果是字典類型,需要反序列化的處理(json.loads())。
4. JSON中,標准語法中,不支持單引號,屬性或者屬性值,都必須是雙引號括起來,用字符串方法replace("'",'\"')進行處理。
18.4.17 接口數據驅動之Excel案例代碼結構的優化(同個文件)
上面已經實現了通過讀取Excel表數據進行參數化,大家可能會說,代碼看起來很亂!確實是有點亂,接下來我們對上面的代碼進行優化。
第一步:定義一個讀取 Excel 表的 readExcel() 方法,參數:rowx 。
def readExcel(rowx):
'''
讀取excel中數據並且返回
:parameter filePath:xlsx文件名稱
:parameter rowx:在excel中的行數
'''
book = xlrd.open_workbook('data.xls')
sheet = book.sheet_by_index(0)
return sheet.row_values(rowx)
第二步:定義一個獲取請求 URL 的方法 getUrl(),參數:rowx 。
def getUrl(rowx):
'''
獲取請求URL
:parameter rowx:在excel中的行數
'''
return readExcel(rowx)[3]
第三步:定義一個獲取請求參數的方法 getData(),參數:rowx 。
def getData(rowx):
'''
獲取請求參數
:parameter rowx:在excel中的行數
'''
# 由於JSON中,標准語法中,不支持單引號,屬性或者屬性值,都必須是雙引號括起來,用字符串方法replace("'",'\"')進行處理
data1 = readExcel(rowx)[4].replace("'", '\"')
# 因為請求參數數據類型是字典,所以進行了反序列化的處理。
data = json.loads(data1)
return data
第四步:用 unittest 單元測試框架編寫測試用例。
完整的程序如下:
import requests
from bs4 import BeautifulSoup
import xlrd
import json
import unittest
def readExcel(rowx):
'''
讀取excel中數據並且返回
:parameter filePath:xlsx文件名稱
:parameter rowx:在excel中的行數
'''
book = xlrd.open_workbook('data.xls')
sheet = book.sheet_by_index(0)
return sheet.row_values(rowx)
def getUrl(rowx):
'''
獲取請求URL
:parameter rowx:在excel中的行數
'''
return readExcel(rowx)[3]
def getData(rowx):
'''
獲取請求參數
:parameter rowx:在excel中的行數
'''
# 由於JSON中,標准語法中,不支持單引號,屬性或者屬性值,都必須是雙引號括起來,用字符串方法replace("'",'\"')進行處理
data1 = readExcel(rowx)[4].replace("'", '\"')
# 因為請求參數數據類型是字典,所以進行了反序列化的處理。
data = json.loads(data1)
return data
class Test(unittest.TestCase):
def setup(self):
print("------開始執行用例--------")
def teardown(self):
print("------用例執行結束--------")
def test_case1(self):
url = getUrl(2)
payload = getData(2)
headers = {
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Referer": "http://127.0.0.1:8090/recruit.students/login/view",
}
# 發送get請求
response = requests.get(url,headers=headers,params=payload)
# 打印請求response后的URL
print(response.url)
# 查看響應內容,response.text 返回的是Unicode格式的數據
print(response.text)
# 查看響應碼
print(response.status_code)
if __name__ == '__main__':
unittest.main(verbosity=2)
運行結果:
18.4.18 接口數據驅動之Excel案例代碼結構的繼續優化(多個文件)
通過上面的優化之后,可能有些人還是覺得一個文件代碼太多,層級不明顯,不好維護,那好,我們接着繼續優化。
第一步,在當前項目目錄下新建一個 Data-Driven 文件夾,把數據文件 data.xls 放到這個目錄下,同時,還需要新建一個 __init__.py 的空白文件(該文件的主要作用是初始化Python包)。在__init__.py文件中編寫內容
from Data_Driven.data_driven import Data_Excel
第二步:在 Data-Driven 文件夾下,新建一個 data_driven.py 文件,在文件中編寫代碼。
import xlrd
import json
class Data_Excel(object):
def __init__(self):
pass
def readExcel(self,rowx):
'''
讀取excel中數據並且返回
:parameter filePath:xlsx文件名稱
:parameter rowx:在excel中的行數
'''
book = xlrd.open_workbook('data.xls')
sheet = book.sheet_by_index(0)
return sheet.row_values(rowx)
def getUrl(self,rowx):
'''
獲取請求URL
:parameter rowx:在excel中的行數
'''
return self.readExcel(rowx)[3]
def getData(self,rowx):
'''
獲取請求參數
:parameter rowx:在excel中的行數
'''
# 由於JSON中,標准語法中,不支持單引號,屬性或者屬性值,都必須是雙引號括起來,用字符串方法replace("'",'\"')進行處理
data1 = self.readExcel(rowx)[4].replace("'", '\"')
# 因為請求參數數據類型是字典,所以進行了反序列化的處理。
data = json.loads(data1)
return data
if __name__ == "__main__":
#定義一個類對象
t= Data_Excel()
url = t.getUrl(2)
print(url)
payload = t.getData(2)
print(payload)
第三步:編寫我們的測試用例。
import os,sys,requests,unittest
sys.path.append("./Data_Driven")
from data_driven import Data_Excel
class Test(unittest.TestCase,Data_Excel):
def setup(self):
print("------開始執行用例--------")
def teardown(self):
print("------用例執行結束--------")
def test_case1(self):
t = Data_Excel()
url = t.getUrl(2)
payload = t.getData(2)
headers = {
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Referer": "http://127.0.0.1:8090/recruit.students/login/view",
}
# 發送get請求
response = requests.get(url,headers=headers,params=payload)
# 打印請求response后的URL
print(response.url)
# 查看響應內容,response.text 返回的是Unicode格式的數據
print(response.text)
# 查看響應碼
print(response.status_code)
if __name__ == '__main__':
unittest.main(verbosity=2)
運行結果:
18.4.19 python跨路徑調用的三種方法
假設路徑結構為:
project
mode
count.py
data.py
test.py
count.py文件里有A類,data.py里有B類,現在想要在test.py中調用count.py和data.py里的方法 。
方法一:
import sys
sys.path.append(“./mode”)
from count import A
from data import B
之后在test.py中直接使用 類名(),方法名() 。
方法二:(推薦)
在 mode 中新建 init.py,內容為空 。
之后在test.py中 。
from model.count import A
from model.new_count import B
之后在test.py中直接使用 類名(),方法名() 。
方法三:
在 model中新建 init.py,內容為 :
from count import A
from new_count import B
之后在test.py中 。
import mode
調用時,mode.類名(),mode.方法名() 。
或
from model import *
調用時,直接使用 類名(),方法名()。
--------------------------
個人今日頭條賬號: 聽海8 (上面上傳了很多相關學習的視頻以及我書里的文章,大家想看視頻,可以關注我的今日頭條)