小編寫這篇文章的主要目的,主要是給大家解讀關于python接口自動化的一些詳細代碼實例,具體是什么呢?下面就給各位讀者詳細的解答下。
前言
我們做接口自動化的過程中,解決端口依賴的相關數據時,一般會采用正則匹配去進行獲取有關的信息。
正則匹配,又被稱為正規表示式、正規表示法、正規表達式、規則表達式、常規表示法(RegularExpression,在編碼中??s寫為regex、regexp或RE)。這是一個特殊的字符序列,它能夠幫助你便利的檢驗一個字符串是否與某種模式匹配。在很多文本編輯器里,正則匹配通常被用來檢索、替換那些匹配某個模式的文本。而Python自1.5版本起增加了re模塊,它提供Perl風格的正則匹配模式。
一、正則表達式語法
1.1表示單字符
單字符:即表示一個多帶帶的字符,比如匹配數字用d,匹配非數字用D。
除以下語法,也可以匹配指定的具體字符,可以是1個也可以是多個。
實例如下,這里先說明一下findall(匹配規則,要匹配的字符串)這個方法是查找所有匹配的數據,以列表的形式返回,后面會在re模塊進行詳解:
import re #.:匹配任意1個字符 re1=r'.' res1=re.findall(re1,'nj8?0nbthnihb') print(res1)#運行結果:['j','8','?','0','b','t','h','i','h','b'] #[]:匹配列舉中的其中一個 re2=r"[abc]" res2=re.findall(re2,'1iugfiSHOIFUOFGIDHFGFD2345a6a78b99cc') print(res2)#運行結果:['a','a','b','c','c'] #d:匹配一個數字 re3=r"d" res3=re.findall(re3,"dfghjkl32212dfghjk") print(res3)#運行結果:['3','2','2','1','2'] #D:匹配一個非數字 re4=r"D" res4=re.findall(re4,"d212dk?n$%3;]a") print(res4)#運行結果:['d','d','k','?','n','$','%',';',']','a'] #s:匹配一個空白鍵或tab鍵(tab鍵實際就是兩個空白鍵) re5=r"s" res5=re.findall(re5,"a s d a 9999") print(res5)#運行結果:['','','','',''] #S:匹配非空白鍵 re6=r"S" res6=re.findall(re6,"a s d a 9999") print(res6)#運行結果:['a','s','d','a','9','9','9','9'] #w:匹配一個單詞字符(數字、字母、下劃線) re7=r"w" res7=re.findall(re7,"ce12sd #a as_#$") print(res7)#運行結果:['c','e','1','2','s','d','a','a','s','_'] #W:匹配一個非單詞字符(不是數字、字母、下劃線) re8=r"W" res8=re.findall(re8,"ce12sd #a as_#$") print(res8)#運行結果:[' ','#','','#','$'] #匹配指定字符 re9=r"python" res9=re.findall(re9,"cepy1thon12spython123 python") print(res9)#運行結果:['python','python']
1.2表示數量
如果要匹配某個字符多次,就可以在字符后面加上數量進行表示,具體規則如下:
實例如下:
import re #*:表示前一個字符出現0次以上(包括0次) re21=r"d*"#這里匹配的規則,前一個字符是數字 res21=re.findall(re21,"343aa1112df345g1h6699")#如匹配到a時,屬于符合0次,但因為沒有值所以會為空 print(res21)#運行結果:['343','','','1112','','','345','','1','','6699',''] #?:表示0次或者一次 re22=r"d?" res22=re.findall(re22,"3 43*a111") print(res22)#運行結果:['3','','4','3','','','1','1','1',''] #{m}:表示匹配一個字符m次 re23=r"1[3456789]d{9}"#手機號:第1位為1,第2位匹配列舉的其中1個數字,第3位開始是數字,且匹配9次 res23=re.findall(re23,"sas13566778899fgh256912345678jkghj12788990000aaa113588889999") print(res23)#運行結果:['13566778899','13588889999'] #{m,}:表示匹配一個字符至少m次 re24=r"d{7,}" res24=re.findall(re24,"sas12356fgh1234567jkghj12788990000aaa113588889999") print(res24)#運行結果:['1234567','12788990000','113588889999'] #{m,n}:表示匹配一個字符出現m次到n次 re25=r"d{3,5}" res25=re.findall(re25,"aaaaa123456ghj333yyy77iii88jj909768876") print(res25)#運行結果:['12345','333','90976','8876']
1.2.1匹配分組
實例如下:
import re #同時定義多個規則,只要滿足其中一個 re31=r"13566778899|13534563456|14788990000" res31=re.findall(re31,"sas13566778899fgh13534563456jkghj14788990000") print(res31)#運行結果:['13566778899','13534563456','14788990000'] #():匹配分組:在匹配規則的數據中提取括號里的數據 re32=r"aa(d{3})bb"#如何數據符合規則,結果只會取括號中的數據,即d{3} res32=re.findall(re32,"ggghjkaa123bbhhaa672bbjhjjaa 45bb") print(res32)#運行結果:['123','672']
實例如下:
import re #^:匹配字符串的開頭 re41=r"^python"#字符串開頭為python res41=re.findall(re41,"python999python")#只會匹配這個字符串的開頭 res411=re.findall(re41,"1python999python")#因為開頭是1,第1位就不符合了 print(res41)#運行結果:['python'] print(res411)#運行結果:[] #$:匹配字符串的結尾 re42=r"python$"#字符串以python結尾 res42=re.findall(re42,"python999python") print(res42)#運行結果:['python'] #b:匹配單詞的邊界,單詞即:字母、數字、下劃線 re43=r"bpython"#即匹配python,且python的前一位是不是單詞 res43=re.findall(re43,"1python 999 python")#這里第1個python的前1位是單詞,因此第1個是不符合的 print(res43)#運行結果:['python']
#B:匹配非單詞的邊界
re44=r"Bpython"#即匹配python,且python的前一位是單詞
res44=re.findall(re44,"1python999python")
print(res44)#運行結果:['python','python']
二、貪婪模式
python里數量詞默認是貪婪的,一直試著搭配盡可能多地字段,并非貪婪模式則是試著搭配盡可能少的字段,在表示數量的表達式后加上問號(?)就可以關閉貪婪模式。
如下所示實例,搭配2個以上的大數字,假如滿足條件它還會繼續獲取到不滿足才終止,如這里面的34656fya,34656符合2個大數字以上,那么它還會繼續獲取到6為止,假如關閉貪婪模式,那么在滿足2個大數字時就會終止,最后可以獲取到34、65。
import re #默認的貪婪模式下 test='aa123aaaa34656fyaa12a123d' res=re.findall(r'd{2,}',test) print(res)#運行結果:['123','34656','12','123'] #關閉貪婪模式 res2=re.findall(r'd{2,}?',test) print(res2)#運行結果:['12','34','65','12','12']
三、re模塊
在python中使用正則表達式,就會用到re模塊來進行操作,提供的方法一般需要傳入兩個參數:
參數1:匹配的規則
參數2:要進行匹配的字符串
3.1 re.findall()
查找所有符合規范的字符串,以列表的形式返回。
import re test='aa123aaaa34656fyaa12a123d' res=re.findall(r'd{2,}',test) print(res)#運行結果:['123','34656','12','123'] 3.2re.search() 查找第一個符合規范的字符串,返回的是一個匹配對象,可以通過group()將匹配到的數據直接提取出來。 import re s="123abc123aaa123bbb888ccc" res2=re.search(r'123',s) print(res2)#運行結果:<re.Match object;span=(0,3),match='123'> #通過group將匹配到的數據提取出來,返回類型為str print(res2.group())#運行結果:123
返回的匹配對象中,span為匹配到的數據的下標范圍,match則是匹配到的值。
group()參數說明:
不傳參數:獲取的是匹配到的所有內容
傳入數值:可以通過參數來指定,獲取第幾個分組中的內容(獲取第1個分組,傳入參數1,獲取第2個分組,傳入參數2,依次類推。)
import re s="123abc123aaa123bbb888ccc" re4=r"aaa(d{3})bbb(d{3})ccc"#這里分組就是前面說到的匹配語法:() res4=re.search(re4,s) print(res4) #group不傳參數:獲取的是匹配到的所有內容 #group通過參數指定,獲取第幾個分組中的內容(獲取第1個分組,傳入參數1,獲取第2個分組,傳入參數2,依次類推.. print(res4.group()) print(res4.group(1)) print(res4.group(2))
3.3 re.match()
從字符串的起始位置進行匹配,匹配成功則返回匹配到的對象,如果開頭的位置不符合匹配的規則,不會繼續往后面去匹配,直接返回None。re.match()與re.search()都是只匹配一個,不一樣的是,前者只匹配字符串的開頭,后者則是會匹配整個字符串,但只獲取第一個符合的數據。
import re s="a123abc123aaa1234bbb888ccc" #match:只匹配字符串的開頭,開頭不符合就返回None res1=re.match(r"a123",s) res2=re.match(r"a1234",s) print(res1)#運行結果:<re.Match object;span=(0,4),match='a123'> print(res2)#運行結果:None
3.4re.sub()
檢索和替換:用于替換字符串中的匹配項
re.sub()參數說明:
參數1:待替換的字符串
參數2:目標字符串
參數3:要進行替換操作的字符串
參數4:可以指定最多替換的次數,非必填(默認替換所有符合規范的字符串)
import re s="a123abc123aaa123bbb888ccc" #<font color="#FF0000">參數1:</font>待替換的字符串 #<font color="#FF0000">參數2:</font>目標字符串 #<font color="#FF0000">參數3:</font>要進行替換操作的字符串 #<font color="#FF0000">參數4:</font>可以指定最多替換的次數,非必填(默認替換所有符合規范的字符串) res5=re.sub(r'123',"666",s,4) print(res5)#運行結果:a666abc666aaa666bbb888ccc
四、用例參數化
在接口自動化測試中,我們的測試數據都是保存在excel中的,有些參數如果寫死一個數據,可能換個場景或者換個環境就不能用了,那么切換環境時就需要先把新環境的測試數據準備好,并且能支持去跑我們的腳本,或者把excel的數據修改為適合新環境的測試數據,維護的成本較高。因此就需要把我們的自動化腳本測試數據盡量地參數化,降低維護成本。
我們先看簡單版的參數化,以登錄為例,登錄時用到的賬號、密碼等信息都可以提取出來放到配置文件,修改數據或更換環境時直接在配置文件中統一修改就可以了。
但如果有多個不同的數據需要參數化呢,每個參數都加個判斷去替換數據嗎?這樣的代碼既啰嗦又不好維護,這時re模塊就可以用上了,直接看一個實例:
import re from common.myconfig import conf class TestData: """用于臨時保存一些要替換的數據""" pass def replace_data(data): r=r"#(.+?)#"#注意這個分組()內的內容 #判斷是否有需要替換的數據 while re.search(r,data): res=re.search(r,data)#匹配出第一個要替換的數據 item=res.group()#提取要替換的數據內容 key=res.group(1)#獲取要替換內容中的數據項 try: #根據替換內容中的數據項去配置文件中找到對應的內容,進行替換 data=data.replace(item,conf.get_str("test_data",key)) except: #如果在配置文件中找不到就在臨時保存的數據中找,然后替換 data=data.replace(item,getattr(TestData,key)) return data
注意這里的正則表達式是有使用?關閉貪婪模式的,因為測試數據中可能會需要參數化2個或以上的數據,如果不關閉貪婪模式,它就只能匹配搭配一個數據,舉例如下:
import re data='{"mobile_phone":"#phone#","pwd":"#pwd#","user":#user#}' r1="#(.+)#" res1=re.findall(r1,data) print(res1)#運行結果:['phone#","pwd":"#pwd#","user":#user']注意這里單引號只有一個數據 print(len(res1))#運行結果:1 r2="#(.+?)#" res2=re.findall(r2,data) print(res2)#運行結果:['phone','pwd','user'] print(len(res2))#運行結果:3
另外提到的一個用于臨時保存數據的類,這里主要用于保存接口返回的數據,因為有些測試數據是動態變化的,可能要依賴于某個接口,后面的測試用例又需要這些數據,那么我們在接口返回時就可以保存到這個類里作為一個類屬性,接著在需要用這個數據的測試用例時,把這個類屬性提取出來替換到測試數據中即可。提示:設置屬性setattr(對象,屬性名,屬性值),獲取屬性值getattr(對象,屬性名)。
到此為止,已經給大家介紹到這里了,希望可以為各位讀者帶來幫助。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127794.html
摘要:下面跟大家詳細分享一下寫爬蟲抓取靜態網站的全過程。而我們上面說的元字符都代表一定的規則和占據一定的字符。 遇到的需求 前段時間需要快速做個靜態展示頁面,要求是響應式和較美觀。由于時間較短,自己動手寫的話也有點麻煩,所以就打算上網找現成的。 中途找到了幾個頁面發現不錯,然后就開始思考怎么把頁面給下載下來。 由于之前還沒有了解過爬蟲,自然也就沒有想到可以用爬蟲來抓取網頁內容。所以我采取的辦...
摘要:爬蟲之簡介提供一些簡單的式的函數用來處理導航搜索修改分析樹等功能。自動將輸入文檔轉換為編碼,輸出文檔轉換為編碼。已成為和一樣出色的解釋器,為用戶靈活地提供不同的解析策略或強勁的速度。 python爬蟲之BeautifulSoup 簡介 **Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。它是一個工具箱,通過解析文檔為用戶提供需要抓取...
摘要:今天我來和大家分享一下以及自動化生成工具的開發經驗。代碼生成工具接著講講代碼生成工具,對于來講,有官方的代碼生成器,還有其他的同類開源項目比如?,F有的代碼生成器沒有可以開箱即用的,都需要去進行不少的修改。 前言 在開發工作中,經常會遇到新產品、服務上線后,需要將其 API 編寫不同語言的 SDK。但不同語言 SDK 中都有很大一部分內容是用來進行 API 的描述,而且這部分代碼量是最大...
摘要:今天我來和大家分享一下以及自動化生成工具的開發經驗。代碼生成工具接著講講代碼生成工具,對于來講,有官方的代碼生成器,還有其他的同類開源項目比如?,F有的代碼生成器沒有可以開箱即用的,都需要去進行不少的修改。 前言 在開發工作中,經常會遇到新產品、服務上線后,需要將其 API 編寫不同語言的 SDK。但不同語言 SDK 中都有很大一部分內容是用來進行 API 的描述,而且這部分代碼量是最大...
摘要:今天我來和大家分享一下以及自動化生成工具的開發經驗。代碼生成工具接著講講代碼生成工具,對于來講,有官方的代碼生成器,還有其他的同類開源項目比如?,F有的代碼生成器沒有可以開箱即用的,都需要去進行不少的修改。 前言 在開發工作中,經常會遇到新產品、服務上線后,需要將其 API 編寫不同語言的 SDK。但不同語言 SDK 中都有很大一部分內容是用來進行 API 的描述,而且這部分代碼量是最大...
閱讀 911·2023-01-14 11:38
閱讀 878·2023-01-14 11:04
閱讀 740·2023-01-14 10:48
閱讀 1982·2023-01-14 10:34
閱讀 942·2023-01-14 10:24
閱讀 819·2023-01-14 10:18
閱讀 499·2023-01-14 10:09
閱讀 572·2023-01-14 10:02