python爬蟲常用庫之requests詳解

sergiojune發表於2019-03-04

這是日常學python的第11篇原創文章


在使用了urllib庫之後,感覺很麻煩,比如獲取個cookie都需要分幾步,程式碼又多,這和python的風格好像有點不太像哈,那有沒有更加容易點的請求庫呢?答案是有的,那就是第三方庫requests,這個庫的作者是大名鼎鼎的kennethreitz,創作這個庫的原因就是想讓python開發者更加容易地發起請求,處理請求。裡面還有個名字:HTTP for Humans,顧名思義,就是用來請求http的。想看原始碼的可以在github上搜尋他的名字就可以看到了。


接下來介紹下怎樣用這個庫吧!


( 這文章原創首發於公眾號[日常學python] )


因為這是第三方庫,所以我們需要下載,需要在命令列輸入

pip install requests
複製程式碼

如果你裝的是anacoda可以忽略這條


安裝好了就來進行使用吧


1
進行簡單的操作

傳送一個get請求

# 傳送請求
import requests

response = requests.get('http://httpbin.org/get')
# 獲取返回的html資訊
print(response.text)
複製程式碼

這樣就傳送了一個get請求,並且還列印了返回的內容,這個不再需要知道網頁是哪個編碼的,不過有時會出現編碼問題,但是你也可以指定編碼型別,如:

response.encoding = 'utf-8'
複製程式碼

指定完成後就可以正常編碼了,前提你得知道網頁的編碼型別。


出了上面這些,我們還可以獲取下面的資訊

print(response.headers)
# 請求狀態碼
print(response.status_code)
# 獲取網頁的二進位制內容
print(response.content)
print(response.url) # 獲取請求的url
print(response.cookies) # 獲取cookie
複製程式碼

是不是覺得很容易,一行程式碼就可以了。不再需要幾步程式碼什麼的了。


接下來被髮爬的話帶上個請求頭來進行請求

# 還可以新增請求頭進行請求
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
response = requests.get('httpbin.org/get', headers=headers )
print(response.headers)
print(response.text)
複製程式碼

加個請求頭也就是加個關鍵字引數而已


還可以進行帶引數的get請求

# 進行帶引數的get請求
data = {'name': 'june', 'password': 123456}
response = requests.get('http://httpbin.org/get', params=data)
print(response.text)
複製程式碼



那如果需要登陸呢?post請求怎樣發?告訴你,照樣很簡單

# 進行post請求
data = {'name': 'june', 'password': 123456}
response = requests.post('http://httpbin.org/post', data=data, headers=headers)
print(response.text)
複製程式碼

是不是很簡單,也是加個data關鍵字引數,把要提交的登陸引數進行post上去。


那除了上面的兩個請求,還能進行別的請求嗎?我可以非常開心地告訴你,可以的。比如,你要發個put請求,如這樣

requests.put()
requests.delete()
複製程式碼

這個就是傳送put請求和delete請求的,其他的請求也是這樣傳送,就不一 一說了。



2
進行復雜點的請求


在登陸的時候我們有時候需要輸入驗證碼,那怎樣輸呢?爬蟲的看不了網頁,最簡單的做法就是把這個驗證碼的圖片下載下來然後手動輸入,那麼我們怎樣下載呢?我們可以向這個圖片的url傳送請求,然後把返回內容以二進位制方法存入檔案裡面就可以了。


程式碼如下:

# 從網上讀取二進位制資料,比如圖片
response = requests.get('https://www.baidu.com/img/bd_logo1.png', headers=headers)
# 這個是直接獲取位元組碼,這個是要儲存的檔案
print(response.content)
# 這個是獲取解碼後的返回內容,這個是亂碼
print(response.text)
# 用檔案來把圖片下載下來
with open('baidu.png', 'wb') as f: # 注意寫的方式是以二進位制方式寫入
f.write(response.content)
print('下載完畢')
複製程式碼


還是很簡單,不得不說,這個庫太好用了。


當我們需要上傳檔案的時候,比如圖片,我們還可以用post方法把他傳送出去

# 上傳檔案
files = {'picture': open('baidu.png', 'rb')}
response = requests.post('http://httpbin.org/post', files=files)
print(response.text)
複製程式碼


獲取cookie並簡單處理一下

# 獲取cookie
response = requests.get('https://www.baidu.com')
for k, v in response.cookies.items():
print(k, '=', v)
複製程式碼


當網頁返回內容是json格式是,我們不需要用json庫來解析,我們可以直接利用requests的方法進行解析,兩者的效果是一樣的

# 解析json
j = response.json() # 可以用json庫來解析,結果一樣
複製程式碼



在urllib庫時儲存登陸資訊需要把cookie儲存下來,但是在requests庫裡面,我們只需要用requests.session()來儲存資訊就可以了。

# 用會話來保持登陸資訊
session = requests.session()
response = session.get('http://httpbin.org/cookies/set/number/123456')
print(response.text)
複製程式碼


這樣就可以儲存登陸了,不需要為cookie操心了,但是每次獲取一個session就可以了,然後用來請求或者其他操作。不需要每次請求或者操作都建立一個sesion出來,這樣是儲存不了登陸資訊的



當一個網站不安全,需要你用證照驗證的,比如這個網站

https://www.12306.cn



這時要訪問裡面的網站內容,我們就需要進行驗證,程式碼如下

# 證照驗證
response = requests.get('https://www.12306.cn', verify=False) # 不加這個關鍵字引數的話會出現驗證錯誤問題,因為這個網站的協議不被信任
複製程式碼

這樣就可以進行訪問了,但是會有一條警告

E:\anaconda\lib\site-packages\urllib3\connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
複製程式碼

覺得不美觀的,我們還可以在請求時加個cert關鍵字引數,值為可信任的證照,為一個元組,寫上賬號和密碼之類的,這裡就不演示了


遇到需要認證的網站,我們也可以這樣

from requests.auth import HTTPBasicAuth
# 設定認證

# requests.get('需要認證的網址', auth=HTTPBasicAuth('user', 'passwd')) # 由於找不到需要認證的網址,所以先寫個主體
# 還可以這樣認證
# requests.get('需要認證的網址', auth=('user', 'passwd')) # 這樣就簡單點
複製程式碼

由於我找不到需要認證的網站,所以就不演示了。


requests還可以用代理ip來進行請求網站來防止ip被封以至於自己爬不了的尷尬。使用代理ip也比urllib庫簡單得多,程式碼如下:

# 設定代理
proxies = {'http': 'http://122.114.31.177:808',
'https': 'https://119.28.223.103:8088'}
# 在請求時新增上列代理
response = requests.get('http://httpbin.org/get', proxies=proxies)
print(response.text)
複製程式碼

上面的字典格式需要一 一對應,然後在請求時加上個關鍵字引數proxies就可以了。


3
請求異常處理


在程式執行時,遇到錯誤時程式就會被強行停止,如果想要繼續執行,就需要進行捕捉異常來讓程式繼續執行。


在requests庫中有個處理異常的庫requests.exceptions


這裡簡單地處理下請求超時的處理情況

import requests
from requests.exceptions import ReadTimeout, ConnectTimeout, HTTPError, ConnectionError, RequestException
# 捕捉異常
try:
response = requests.get('http://httpbin.org/get', timeout=0.1) # 規定時間內未響應就丟擲異常
print(response.text)
except ReadTimeout as e:
print('請求超時')
except ConnectionError as e:
print('連線失敗')
except RequestException as e:
print('請求失敗')
複製程式碼


這裡捕捉了三個異常,因為ReadTimeout是ConnectionError的子類,所以先捕捉ReadTimeout,再捕捉父類的。而ConnectionError 和 RequestException 同理


更多的異常處理可以檢視文件哈。


4
最後

以上均是我在學習時的筆記和個人在運用時遇到的一些坑都簡單地記載了上去,希望對你有用哈,如果想看更多的用法可以去官方文件檢視。還有程式碼我放在了github上,要的話可以上去檢視。


GitHub:github.com/SergioJune/…

官方文件:docs.python-requests.org/zh_CN/lates…

學習參考資料:https://edu.hellobi.com/course/157





1803114089.png


日常學python

一個專注於python的公眾號


相關文章