python發送網絡請求是經過模塊中的方法來實現的,模塊定義好了請求的語法格式,只須要按照相應的語法格式對號入座寫代碼便可。html
通常來講咱們測試的都是基於HTTP和HTTPS的網絡請求,python有不少自動帶的原生模塊和擴展模塊都可以模擬網絡請求。固然咱們在實際工做中會遇到不少其餘協議請求,如WebSocket等。python
本章以HTTP協議爲例,採用原生模塊和擴展模塊對比的方式,給你們剖析一下原理。原理性的東西雖然普遍不被重視,但它對你們以後的學習是十分有好處的。web
5.1 發送HTTP請求chrome
5.1.1 requests模塊json
python有不少模塊均可以發送HTTP請求,包括原生的模塊http.client,urlib2等,第三方模塊requests等,都封裝了發送HTTP請求的方法。因爲原生的模塊過於複雜,不推薦使用,以後全部的請求都是基於第三方模塊requests進行的,該模塊的好處在於簡單,把請求的框架都搭建好了,只須要填入相應的參數數據,就能發送網絡請求了。api
requests模塊非原生模塊,全部要使用還須要先進行安裝,按照以前安裝模塊的方法,打開命令行(在運行中輸入cmd),而後在命令行輸入:瀏覽器
pip install requests服務器
接前就會自動安裝requests模塊及其相關模塊,而後就能夠引入該模塊使用其提供的方法了。cookie
import requests網絡
後面會經過一些實例來介紹requests的具體使用方法。
5.1.2 請求與響應
HTTP就是發送請求和獲取響應的一個過程,而requests模塊只須要一步就能完成這樣的一個過程,而且request支持全部的HTTP請求的方法和響應數據,先進行語法介紹:
r = requests.方法(url, headers, data, ...)
其中url參數爲必填的,畢竟HTTP請求就是對指定的URL進行發送,其餘各類參數可根據實際請求的須要選擇性使用。
發送請求後會獲取響應結果,而後把結果賦值給變量,最後經過變量的屬性值取出須要的結果,下面就是經常使用返回結果:
r.headers 獲取返回的頭信息
r.text 獲取返回的主體(其實就是網頁html)
r.cookies 獲取返回的cookies
r.status_code 獲取返回的狀態碼(一般會經過狀態碼判斷請求是否成功)
學會requests的請求方法和獲取響應的結果,就能夠開始網絡請求的測試了,下面就經過代碼實例來熟悉requests的模塊吧。
5.1.3 請求參數
1.URL參數
URL是惟一的必填參數,既然是網絡請求,必需要有URL地址才能發送,就像快遞必定要寫目的地才能發件同樣。先從最簡單的HTTP請求講起,請求一個靜態頁面,好比訪問網易首頁,經過抓包能夠看到該請求是用的get方式發送的,全部要調用requests的get()方法來發送請求。
以網易首頁做爲請求例子,實例代碼:
import requests # 導入requests模塊;
test_url = "http://www.163.com" # 定義url
response = requests.get(test_rul) # 實例化requests.get()方法
print(response.status_code) # 輸出返回的狀態碼
print(response.headers) # 輸出返回的頭信息
print(response.text) # 輸出返回的主體
代碼說明:
1 導入requests模塊;
2 將網易首頁的URL賦值到變量test_url中(這樣的好處在於看起來清晰,也方便代碼從此的維護);
3 在get()方法中將變量test_url直接傳入,即完成了帶URL的get請求(結果會賦值到變量reponse中,reponse中包含了返回結果的全部數據,能夠根據須要獲取想要的數據);
四、五、6 獲取並打印返回的結果(狀態碼、頭信息、主體)
運行結果以下圖:
能夠看出經過requests發送的HTTP請求只有3行代碼,就那麼簡單的一行代碼完成整個請求。
整個請求過程全被封裝在方法之中,對於沒有編碼基礎的測試人員來講再適合不過了。
二、headers 參數
headers是最經常使用的參數之一,前面那個例子只是最簡單的請求,沒有帶其餘參數信息,而不少時候須要帶入headers發送請求,才能夠獲取相應的請求結果。
仍是以網易首頁做爲例子,若是是pc端的請求,會返回pc端的頁,若是是手機端的請求,則返回手機端的頁面,這時候就要帶上headers參數的請求,經過瀏覽器的抓包工具能夠看到headers有個字段「User-Agent",而服務器就是根據這個字段來判斷訪問的來源,若是須要模擬手機端請求,須要將「User-Agent"改成請求的手機型號。
實例代碼:
import requests
test_url = "http://www.163.com"
h = {"User-Agent":"Android/H60-L01/4.4.2"} # 將headers賦值到變量h中;
reponse = requests.get(test_url, headers=h) # 在get()方法中加一個headers參數,而後將變量賦值給headers參數。
print(reponse.status_code)
print(reponse.headers)
print(reponse.text)
運行結果以下:
三、cookies 參數
cookies也是最經常使用的參數之一,由於只要涉及登陸後數據獲取,都須要用到cookies參數,那麼如何獲取到cookies呢,一種是經過post發送登陸請求,獲取返回值的cookies屬性(這個會在後面的實例中講解),還有一種就是經過瀏覽器的網絡抓包方式獲取,在還不會熟練使用request模塊的前提下,就先介紹如何經過抓包獲取cookies。
首先打開chrome瀏覽器,而後登陸網易郵箱(或其它網站),接着按F12(或在網頁右鍵,選擇檢查)打開開發者工具,抓取cookies的界面以下圖:
選擇application中的cookies,點擊對應的測試URL域名,再找到session屬性而且domain是對應測試請求的域名,而後這條信息name和value對應的就是cookies了。
cookies參數以字典的形式發送,只須要對應的將name和value傳入便可。
實例代碼:
import requests
c = {"JSESSIONID":"abcRPAFmBY_sqf2qRMmxw"}
test_url = "https://www.163.com/"
reponse = requests.get(test_url, cookies=c)
print(reponse.status_code)
print(reponse.headers)
print(reponse.text)
代碼說明:
2 將瀏覽器抓取的cookies信息以字典的形式賦值到變量c之中;
4 在get方法中加一個cookies參數,而後將變量c賦值給cookies參數,即完成了帶着cookies信息的get請求。
其實cookies也是能夠經過headers參數傳遞的,只是不一樣之處在於cookies是以字典的形式發送的,而在headers之中cookies只是其中一個鍵,因此須要把cookies放到該鍵對應的值裏面,而對應的值是以key=value的形式傳入的,改一下代碼。
import requests
c = {"JSESSIONID":"abcRPAFmBY_sqf2qRMmxw"}
test_url = "https://www.163.com/"
reponse = requests.get(test_url, headers={"cookies":c}) # 此處cookies是做爲headers的鍵值傳入;
print(reponse.status_code)
print(reponse.headers)
print(reponse.text)
代碼說明:
4 在get方法中將變量c賦值給headers參數中的cookies字段,即完成了帶着cookies信息的get請求。
以上的兩種方法,推薦使用cookies參數,一方面把cookies單獨分離出來,不用與其餘headers的字段放在一塊兒,讓代碼更清晰,另外一方面經過post請求返回的cookies是能夠直接賦值到cookies參數之中,不須要再作轉換。
四、params 參數
對於params參數能夠存放請求的表單,並會以key1=value1&key2=value2&key3=value3的形式跟進URL以後發送,爲了區分URL和參數,最好不要把表單放在URL之中,能夠經過params參數進行發送, 上面網易郵箱的URL也是帶着參數的,直接放在URL之中,若是使用params參數就能夠把後面的參數和URL分離。
仍是以博客園登陸界面爲例,只是URL部分把參數進行分離,代碼以下:
import requests
# test_url = "https://passport.cnblogs.com/user/signin?ReturnUrl=https%3A%2F%2Fwww.cnblogs.com%2F"
test_url = "https://passport.cnblogs.com/user/signin"
p = {"ReturnUrl":"https%3A%2F%2Fwww.cnblogs.com%2F"}
reponse = requests.get(test_url, params=p)
print(reponse.status_code)
print(reponse.headers)
print(reponse.text)
代碼說明:
4 將須要發送表單以字典的形式賦值到變量p之中。
5 在get方法中加一個params的參數,而後將變量p賦值給params參數,即完成了帶着params信息的get請求。
若是不使用params參數,也能夠直接把表單加在URL中,只是代碼不清晰,因此不推薦直接把表單加在URL中。
五、data 參數
data參數也是用於存放請求表單,是request模塊中最重要的參數之一。
在使用data以前,先來了解一下post提交數據類型,區別與params,params只有一種類型(字符串類型),而post能夠提交4種類型的數據,至於須要提交什麼類型的數據,取決於服務器接收的數據類型。post的數據類型須要和服務器接收的一致,否則服務器就沒法正常識別post的數據,致使測試結果報錯。就像協議同樣,接收方預約接收哪一種類型的表單,而後發頭方按照接收方指定的協議發送表單,這樣就完成了一個表單的提交。
如何識別服務器接收的數據類型?最簡單的方式仍是抓包。抓取數據類型的界面以下:
經過抓包能夠看到,在request headers 中有一個content-type的字段,這個字段表示了post發送數據的類型,通常分爲如下4種類型:
第1種:content-type:application/json
實際上,如今愈來愈多的人反application/json做爲請求頭,用來告訴服務器消息主體是序列化後的json字符串。因爲json規範流行,除了低版本IE以外的各大瀏覽器都原生支持json.stringify,服務器端語言也都有處理json的函數,而且json格式支持比鍵值對更加複雜的結果化數據。
第2種:content-type:application/x-www-form-urlencoded
這是最多見的post提交數據的方式,瀏覽器的原生form表單,若是不設置enctype屬性,那麼最終就會以application/x-www-form-urlencoded方式提交數據。提交的數據按照key1=value1&key2=value2的方式進行編碼,key和value都進行了URL轉碼,而後打包發送到服務器。
第3種:content-type:multipart/form-data
content-type爲multipart/form-data方式,主要用於上傳文件。須要注意的是同時form的enctype屬性也要設置爲multipart/form-data,才能正確提交併解析所傳輸的數據。
第4種:content-type:text/xml
它是一種使用http做爲傳輸協議,XML做爲編碼方式的遠程調用規範。考慮到XML結構仍是過於臃腫,通常場景用json會更靈活方便,因此這種提交咱們的工做中實際使用的很少,僅瞭解一下就能夠了。
最多見的是 第2種 類型,直接將數據以{key:value}的字典形式賦值給表單,而後經過request.post()中的data參數傳遞就能夠了。
以網易音樂爲例,搜索一首歌曲,經過抓包能夠看到content-type是application/x-www-form-urlencoded,網易音樂的數據類型抓取圖以下:
搜索一首」一次就好「,經過抓包會發現有進行加密,那就直接把加密後的內容放到form之中發送出去,網易音樂的表單抓取以下圖:
實例代碼:
import requests
test_url = "https://music.163.com/weapi/search/suggest/web?csrf_token="
f = {"params":"ShQVLipkE8Y/p89iMoKOX5whEin1ZyoKeXZJJe+rBg+8mrEQT3RaAR5UP5B+ayoKrPIVzxsVuuFA1askCPcBzRJ6qOoPsPz06xStotZZGTmHrzaz1RcbiRpYOOrZl8NC",\
"encSecKey":"9ac26cbd1a87fd9790fb1cc2f0a475a5cd24be6b73e1b516f86b00ab58b568c0d4303eb6314bbedf5adedb968f047f44bb6ebe1fd9cfa09339a781d762e8aba0184c8a57dc53d1717f89d5c85d02e635cec9e7610fac4faac33838a3f299a1aa672390e4430b21ee2ea03e37aee53d17d70973933ffdf3fc7872101a9ff973da"\
}
reponse = requests.post(test_url, data=f)
print(reponse.status_code)
print(reponse.headers)
print(reponse.text)
代碼說明:
3 將須要發送的表單以字典形式賦值到變量form之中。
4 在post方法中加一個data參數,而後將變量賦值給data參數,即完成了帶着表單信息的post請求。
運行結果以下圖:
以上內容來自《python測試之道》——楊燕林、朱對洲、石贇 編著,如有侵權請聯繫刪除。