python的requests庫是我平時用的最多的一個庫,無論是做接口測試,還是寫爬蟲,都離不開它,今天針對它做一個總結
先貼出來官方文檔地址:https://requests.readthedocs.io/zh_CN/latest/index.html
1.requests發送get請求和post請求的姿勢
get請求的參數可以作為后綴,放在url中;也可以用一個字符串字典的方式傳遞這些參數
1. 參數在url中 response = requests.get("https://www.baidu.com/?tn=87048150_dg&ch=1") 2.參數獨立傳遞 payload = {'key1': 'value1', 'key2': 'value2'} # 定義參數 response = requests.get(url, params=payload) # 使用params關鍵字接收參數
post請求的參數一般是放在請求body中,不會直接暴露在url中,post請求是用data關鍵字接收參數的
payload = {'key1': 'value1', 'key2': 'value2'} r = requests.post(url, data=payload)
2.添加headers/查看響應headers
在做爬蟲時,有時需要添加一些請求頭,在requests中添加請求頭也非常方便
headers={ "authority": "music.163.com", "method": "GET", "path": "/", "scheme": "https", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", "accept-encoding": "gzip,deflate,br", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "max-age=0", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" } response = requests.get(url=url, params=data, headers=header)
如果想查看服務返回的請求頭信息,可以通過如下方式獲取
response.headers
如果想查看發送到服務器的請求頭信息(有時候想看下發送的headers是不是和自己寫的headers真的一樣)
response.request.headers
3.超時處理
在發送請求時,最好設置超時等待時間,避免因為某些原因,程序無休止地等待下去
requests庫通過 timeout
參數設定超時等待時間,當超過等待時間,則跳過這個請求(時間單位為 秒)
response = requests.get(url=url, params=data, headers=header, timeout=10)
舉一個例子,演示下我在爬蟲時是如何使用的
下面這段示例代碼,是請求谷歌搜索頁面,但是因為被牆的原因,是無法請求成功的
1、定義一個循環
2、try語句下表示每次循環都請求一次谷歌搜索,超時時間設置為5s
3、except語句下捕捉Timeout錯誤,也就是當請求超時時,執行其下的語句,在這里打印了每次請求時的報錯信息,這樣就不會一直等下去了
import requests url = "https://www.google.com/?hl=zh_CN" for t in range(3): try: r = requests.get(url, timeout=5) print("第{}次請求".format(t))
except requests.exceptions.ConnectTimeout as e: print("第{}次請求報錯:".format(t), e)
運行結果
4. 使用cookie或session
有些網站需要校驗身份,當我們使用賬號密碼登錄后,瀏覽器會生成一條或多條cookie信息,后面如果你如果在發送請求時加上這些cookie信息,就不需要再進行登錄操作了,可以直接訪問(例如postman、jmeter等添加cookie)
發送你的cookies到服務器,可以使用 cookies
參數:
r = requests.get(url, cookies=cookies)
可以用response.cookies來查看響應中的cookie信息,它返回的是CookieJar對象,打印結果如下,可以看到一共包含3段cookie
打印一下類型
print(type(response.cookies))
如果你知道cookies中某個cookie的名稱,那么可以通過如下方式單獨查看這段cookie的值是什么
print(response.cookies["wordpress_logged_in_b4a55cc11ee65809b7e33131f1779846"]) # 括號中的內容是cookie的name
舉個實際應用的栗子,先通過登錄接口獲得登錄后的cookie,然后后續再發送其他請求時都傳入這個cookie,這樣就免登錄了
response = requests.post(url, data=data, headers=headers) # 假如這個是登錄接口,先發起登錄 cookies = requests.utils.dict_from_cookiejar(response.cookies) # 調用登錄成功后,提取響應中的cookie,並使用requests.utils.dict_from_cookiejar()轉成字典格式(因為要使用cookies參數傳遞cookie信息的話,對應的值需要是字典格式)
后續發送請求時,如下:
r = requests.get(url, params=data, headers=header, cookies=cookies, timeout=10)
上面說的方法有一個弊端,每次在發送請求時都要調一下登錄接口來獲取cookie,所以每次的cookie都不一致,這樣就顯得啰嗦了,因為沒有必要一直獲取cookies,只要拿到第一次登陸時的cookies就好了,在cookies過期前可以一直使用它
requests中的會話對象讓你能夠跨請求保持某些參數。它也會在同一個 Session 實例發出的所有請求之間保持 cookie,所以就涉及到了session有時在發送一些請求時需要保持登錄狀態,
s = requests.Session() # 開啟一個會話Session
jar = requests.cookies.RequestsCookieJar() # 創建一個Cookie Jar對象 jar.set('49BAC005-7D5B-4231-8CEA-1XXX39XEACD67','ckXXXX001') # 向Cookie Jar對象中添加cookie值 jar.set('JSESSIONID','F4FFF69BXXXX0F0C8DCB4C061C0') jar.set('JSESSIONIDSSO','9D49C76FDXXXXF5B0F294242B44A') s.cookies.update(jar) # 把cookies追加到Session中
r = s.post(url, headers=header, data=data) # 使用session發送請求
5.請求與響應對象
requests官方文檔有這樣一段話:
任何時候進行了類似 requests.get() 的調用,你都在做兩件主要的事情。
其一,你在構建一個 Request 對象, 該對象將被發送到某個服務器請求或查詢一些資源。
其二,一旦
requests
得到一個從服務器返回的響應就會產生一個Response
對象。該響應對象包含服務器返回的所有信息,也包含你原來創建的Request
對象。
解釋一下
r = requests.get(url, params=data, headers=header, cookies=cookies, timeout=10)
也就是說 執行requests.get()時會先構建一個Request對象
然后服務器響應后會得到一個Response對象,並把它賦給變量r,后面的諸如查看響應狀態碼、響應內容等都是通過這個Response對象來獲得的
下面是常見的訪問響應內容的方法
1、查看響應狀態碼 response.status_code 2、設置編碼(避免響應內容亂碼,也可以指定編碼格式,一般情況下不需要指定,因為它自己會根據響應內容猜測編碼) response.encoding = 'utf-8' 3、查看文本格式響應內容 response.text 4、如何返回json格式的響應內容 Requests 中也有一個內置的 JSON 解碼器,助你處理 JSON 數據 response.json() 或者引入json模塊,使用 json.loads(response.content) 5、二進制響應內容 以字節的方式訪問請求響應體,對於非文本請求,例如爬取視頻、圖片等 response.content
6、再看post請求如何發送數據
requests發送get請求不需要多說,因為它的參數形式比較簡單,這里需要再提一點關於post請求傳參的問題
應該知道post的請求參數有如下幾種:表單格式,如form-data、x-www-form-urlencode;json格式字符串,不同的參數形式對應不同的寫法
payload = {'key1': 'value1', 'key2': 'value2'} 1、如果想要發送一些編碼為表單形式的數據,只需簡單地傳遞一個字典給 data 參數。你的數據字典在發出請求時會自動編碼為表單形式:
r = requests.post(url, data=payload) 2、發送json格式的數據 (1)先在headers中聲明Content-Type: "application/json" (2)發送請求
r = requests.post(url, data=json.dumps(payload), headers=headers) 或者 r = requests.post(url, json=payload)
暫時就這些吧,以后有新的或者說錯的地方再補充修改