python網絡爬蟲之二requests模塊


requests http請求庫
requests是基於python內置的urllib3來編寫的,它比urllib更加方便,特別是在添加headers,
post請求,以及cookies的設置上,處理代理請求,用幾句話就可以實現,而urllib比較繁瑣,
requests比urllib方便多了,requests是一個簡單易用的http請求庫。

官方網站是:
簡單實例:
import requests 
response = requests.get("https://www.baidu.com/")
print(type(response))
print(response.status_code)
print(type(response.text))
print(response.text)
print(response.cookies)

這樣我們就很方便的把請求的cookies獲取出來了。

各種請求方式:
import requests
requests.get("http://httpbin.org/get")
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")


一.基本的GET請求
1. 基本的http get請求:
import requests
response = requests.get("http://httpbin.org/get")
print(response.text)
我們可以通過response.text獲取請求內容。

2. 帶參數的get請求
import requests
response = requests.get("http://httpbin.org/get?name=germey&age=22")
print(response.text)
帶參數請求:我們只需在鏈接地址后面加問好?然后后面帶參數的名和值,參數和參數
之間用與&隔開。
另外requests函數也提供了一個params參數,可以代表用戶向瀏覽器的請求,這樣我們
就可以使用json字典的形式傳遞參數:
如:
格式如下:
response = requests.get(url,params=data)

import requests
data = {
    "name":"germey",
    "age":22
}
response = requests.get("http://httpbin.org/get",params=data)
print(response.text)

3. 解析成json格式數據,這樣方式在ajax請求的時候非常常用。
import requests
import json
response = requests.get("http://httpbin.org/get")
print(type(response))            #是一個class返回對象<class 'requests.models.Response'>
print(type(response.text))       #是一個字符串文本對象<class 'str'>
print(response.text)             #是一個字符串文本
print(type(response.json()))     #是一個json字典對象<class 'dict'>
print(response.json())           #是一個json字典文本,數據與下面相同
print(json.loads(response.text)) #是一個json字典文本,數據與上面相同
#而json.loads實際上是對返回的字符串對象進行一個json序列化操作,
#實際上json.loads(response.text)=response.json()


4. 獲取二進制數據
是指下載文本數據,圖片,視頻時的下載對象,此時需要將文本,圖片,視頻等數據轉換
成二進制數據,然后再將文本,圖片,視頻等數據保存到文件,此時我們就可以得到我們
想要的文本,圖片和視頻等數據了。
import requests
response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
print(type(response.text))           #是一個字符串文本對象<class 'str'>
print(type(response.content))        #是一個bytes字節碼對象<class 'bytes'>
print(response.text)                 #是一個string格式的亂碼字符串
print(response.content)              #是一個字節碼的bytes字節流

#下載文本,圖片,或者視頻的方法:
import requests
response = requests.get("https://avatars1.githubusercontent.com/u/29205487?s=40&v=4")
with open("1.jpg","wb") as f:
    f.write(response.content)
f.close()
#經過上面的驗證,此時我們就可以根據以上方法獲取文件,圖片,或視頻的的文件。此時我們需要
#將文件,圖片,或視頻鏈接地址傳進去,然后將獲取的文件,圖片,或視頻一字節流的形式寫入到
#文件,此時我們打開文件,就可以獲取到我們想要的文本,圖片,或視頻的的文件

#通過以上我們可以得出結論,如果獲取字符串或者是二進制字節流信息,我們字節可以調用text或者
#content方法,但是如果我們想要獲取json格式的字典數據,后面還得加一個括號,因為json不是原生
#自動轉過來的,而是可以看成根據text文件二次轉過來的。


5. 添加headers
添加headers是非常重要的,有時候我們在使用爬蟲獲取數據的時候,如果不添加headers,服務可能會
直接把我們禁掉,或者是服務器出出現請求或者回復錯誤等響應,我們以爬取知乎網站為例,如果我們
不添加headers,那么服務器會返回一個500狀態碼等一個這樣的錯誤,如:
import requests
response = requests.get("https://www.zhihu.com/")
print(response.text)
此時會提示500錯誤。

添加瀏覽器的headers,其實就是偽裝成一個瀏覽器。
import requests
headers = {
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
response = requests.get("https://www.zhihu.com/",headers=headers)
print(response.text)

關於headers內部的參數,我們可以從一個瀏覽器里面提取,在瀏覽器里面的請求參數中的:
user-agent字段,即代表了我們請求服務器所用的瀏覽器客戶端信息,此時我們將他復制下來,
添加到headers字典中即可。

二.POST請求

1.基本的post請求:
post是將數據以form表單的形式傳給服務器,此時我們需要以一個data數據字典的形式作為數據傳遞過去,
例如:
import requests
data = {"name":"germey","age":"22"}
response = requests.post("http://httpbin.org/post",data=data)
print(response.text)


2. post請求添加headers:
import requests
data = {"name":"germey","age":"22"}
headers = {
          'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
response = requests.post("http://httpbin.org/post",data=data,headers=headers)
print(response.text)
print(response.json())

三.返回的response屬性:
import requests
response = requests.get("http://www.baidu.com/")
print(type(response.status_code),response.status_code)            
print(type(response.headers),response.headers)       
print(type(response.cookies),response.cookies)             
print(type(response.url),response.url)     
print(type(response.history),response.history)

response回復帶有很多屬性,常用的屬性有:
1. 狀態碼: response.status_code   int類型
2. headers:response.headers       字典類型
3. cookies: response.cookies       cookies類型
4. url:     response.url           這個url就是我們請求的url          
5. history: response.history       list元組類型,我們訪問的歷史記錄

1. 狀態碼的判斷,我們的瀏覽器都有一個狀態碼的分組,我們可以給根據這個狀態碼來進行一些
判斷:
常見的有:
#請求成功的狀態碼:
100  狀態碼的名字
200  狀態碼的名字是ok
#redirect error:
300
#client error:
400
#server error:
500
另外每一個狀態碼都有一個自己的名字,我們也可以調用這個狀態碼的名字來進行判斷,而不用記住
特定的狀態碼了,例如200的狀態碼是ok,此時我們就可以通過以下兩種方式來驗證判斷。
第一種方式,通過狀態碼來進行驗證:
即驗證:if response.status_code == 狀態碼
import requests
response = requests.get("http://www.baidu.com/")
exit() if not response.status_code == 200 else print("Request Successfully")
此時打印:
Request Successfully
第一種方式,通過狀態碼的名字來進行驗證:
即驗證:if response.status_code == requests.codes.狀態碼的名字(即請求狀態碼的名字)。
import requests
response = requests.get("http://www.baidu.com/")
exit() if not response.status_code == requests.codes.ok else print("Request Successfully")
此時打印:if response.status_code == 狀態碼
Request Successfully

四.requests的其他的一些高級操作

1.文件上傳
import requests
files = {'file':open("1.jpg","rb")}   #在這指定上傳后的文件名,我們也可以指定其他名字。
response = requests.post("http://httpbin.org/post",files=files)
print(response.text)

2.獲取cookies
我們可以直接通過response.cookies這個屬性,就可把cookies獲取打印出來了,這個cookies實際上
是一個列表的形式,因此可以表示成這種形式:response.cookies.items(),這樣我們就可以通過
for循環的形式把這些cookies打印出來,他們都是一個個key-value結構形式的數據。
import requests
response = requests.get("https://www.baidu.com/")
print(response.cookies)
for key,value in response.cookies.items():
    print(key + 'n' + value)

3.會話維持
cookies是做會話維持的,有了這個cookies,我們就可以模擬一個用戶一直維持在一個登陸狀態,相當於
一個用戶在一個瀏覽器里面一直維持登陸狀態的操作。
import requests 
requests.get("http://httpbin.org/cookies/set/number/123456789")  #先為這個網站設置一個cookies
response = requests.get("http://httpbin.org/cookies")            #然后我們就可以把當前的這個網站的cookies拿到
print(response.text)
此時我們打印:
{
  "cookies": {}
}
#通過上面可以看到,我們獲取的cookies是0,沒有,其實根本原因也就是上面我們發起的兩次請求
#分別是兩個獨立的過程,我們可以理解為,我們用一個瀏覽器設置了一個cookies,然后再用另外一個
#瀏覽器訪問,也就是這個兩個請求是獨立的,此時我們需要模擬在一個瀏覽器里面操作,模擬一個set
#和get cookies的操作,此時就得用到如下方法。

requests提供了一個Session的對象,我們可以通過聲明一個Session的對象,然后再用這個Session對象
發起兩次get請求,那么這兩次請求就相當於在一個瀏覽器里面操作了。
import requests 
s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123456789")
response = s.get("http://httpbin.org/cookies")
print(response.text)
此時打印:
{
  "cookies": {
    "number": "123456789"
  }
}
#這個方法非常常用,假如我們再做模擬登錄驗證的時候,可以創建這么一個session對象,
#然后用這個session post一下用戶名和密碼,這樣我們就相當於登錄了,然后我們再用這個
#session對象進行操作,此時我們就會維持這么一個登錄信息,我們就相當於再登錄狀態下操作
#了,此時我們就可以獲取一些登錄后的頁面了,假如我們再做模擬登錄的話,我么可以使用
#requests.Session這個對象來操作。

4.證書驗證
現在的很多網站都是以https格式的網站了,假如入我們查看12306的網站,此時會提示一個ssl證書錯誤,
因為我們的爬蟲程序沒有ssl證書,因此在爬取數據或者與網站交互的時候會提示ssl錯誤。
此時,我們假如使用requests模塊請求一個https網站的時候,可以使用兩種方法來處理:
第一種方式:如果網站使用了不合法的證書,比如網站自己自己創建了以個證書,此時我們可以使用一個
參數verify=False來忽略這個證書,如果是合法的證書的話,也可以使用verif=False這個參數來忽略這個
證書,但是后面也會提示
例如:直接請求12306網站:
import requests
response = requests.get("https://www.12306.cn/")
print(response.status_code)
此時會提示ssl證書錯誤。

我們加一個參數verify=False訪問,
import requests
response = requests.get("https://www.12306.cn/",verify=False)
print(response.status_code)
此時就可以正常訪問操作了。
但是此時會打印信息如下:
C:\Program Files (x86)\Python\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)
200

從上面信息我們可以看到,雖然我們將證書驗證設置為False之后,但是在輸出結果還是會提示一個警告warnings
的信息,提示最好加一個證書,此時我們通過requests模塊導入一個叫做urllib3的原生的包,然后通過調用這個
urllib3的一個disable_warning方法來消除這些警告信息,如from requests import urllib3,經過測試,我們也
可以直接導入這個urllib3的包。
如下所示:
import requests
import urllib3
urllib3.disable_warnings()
response = requests.get("https://www.12306.cn/",verify=False)
print(response.status_code)


第二種方式.我們可以手動使用cert參數指定一個證書的驗證,此時需要添加一個cert參數,此時我們的請求就會
自動的通過這個CA證書進行驗證了,如下所示:
import requests
response = requests.get("https://www.12306.con/",cert=("/path/server.crt","/path/key"))
print(response.status_code)

5.代理設置
第一種方式:http代理
我們只需設置一個proxies代理的字典,然后將這個代理傳過去既可以了。
import requests
proxies = {
   "http":"http://127.0.0.1:10010",
   "https":"https://127.0.0.1:10011",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)
此時我們就可以使用我們的代理來訪問網站了。
假如我們的代理需要用戶名和密碼,此時我們可以在代理前面添加一個用戶名和密碼,然后加一個
'@'符,此時我們就可以訪問了,如下所示:
import requests
proxies = {
   "http":"http://user:password@127.0.0.1:10010",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)

第二種方式:使用socks代理:
此時我們需要安裝一個requests[socks]模塊
pip install requests[socks]
import requests
proxies = {
   "http":"socks5://127.0.0.1:10010",
   "https":"socks5://127.0.0.1:10011",
}
response = requests.get("https://www.taobao.com/",proxies=proxies)
print(response.status_code)
此時我們就可以通過socks代理來進行訪問了。

6.超時的設置:
超時的設置,實際上就是設置一個timeout,假如我們在請求一個網站時,限制一個超時時間的設置,
此時我們可以設置一個timeout的參數。
如下:
import requests
response = requests.get("https://www.taobao.com/",timeout=1)
print(response.status_code)
此時能正常訪問。
如果我們設置個一個較短的時間,比如0.001秒,那么他就會拋出一個
import requests
response = requests.get("https://www.taobao.com/",timeout=0.001)
print(response.status_code)
此時就會出現瀏覽器訪問超時錯誤,提示拋出一個如下的ReadTimeout的異常:
#requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.taobao.com', port=443): 
#Read timed out. (read timeout=0.01)     
import requests
from requests.exceptions import ReadTimeout
try:
     response = requests.get("https://www.taobao.com/",timeout=0.01)
     print(response.status_code)
except ReadTimeout:
     print("timeout")
此時就會輸出一個:
#timeout

7.認證設置
有的網站訪問的時候需要輸入一個用戶名和密碼才能登錄訪問,登錄以后我們才能看到網站頁面里
的內容,假如我們遇到這樣一個需要登錄驗證的網站,requests模塊提供了一個auth參數,我們就
可以通過這個auth傳入一個HTTPBasicAuth參數把用戶名和密碼傳過來,這樣的話我們就可以正常
登錄進去完成一個正常的請求。
假如我們不傳入用戶名和密碼,直接請求:
import requests
response = requests.get("http://www.11111.com")
print(response.status_code)
此時就會返回請求被禁止的401狀態碼:
輸入如下:
#401
此時我們可以使用auth將我們的用戶名和密碼傳過去:
第一種方法,直接傳入一個字典:
import requests
response = requests.get("http://www.11111.com",auth=('username','password'))
print(response.status_code)

第二種方法,通過HTTPBasicAuth傳入一個字典,這兩種方式都可以。
import requests
from requests.auth import HTTPBasicAuth
response = requests.get("http://www.11111.com",auth=HTTPBasicAuth('username','password'))
print(response.status_code)

此時就可以正常訪問了。

8.關於異常處理的部分
import requests 
from requests.exceptions import ReadTimeout,HTTPError,ConnectionError,

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM