學習爬蟲之前呢,最好要對HTTP協議有了解,我前面有寫過幾篇關於HTTP協議的文章,建議讀者閱讀一下,對爬蟲幫助很大。
1. requests 庫的幾個主要方法
方法 | 說明 |
---|---|
requests.request() | 構造一個網頁請求,支撐以下各方法的基礎方法 |
requests.get() | 獲取HTML網頁的主要方法,對應於HTTP的GET |
requests.head() | 獲取HTML網頁頭信息的主要方法,對應於HTTP的HEAD |
requests.post() | 向HTML頁面提交POST請求的方法,對應於HTTP的POST |
requests.put() | 向HTML頁面提交PUT請求的主要方法,對應於HTTP的PUT |
requests.patch() | 向HTML頁面提交局部修改請求,對應於HTTP的PATCH |
requests.delete() | 向HTML頁面提交刪除請求,對應於HTTP的DELETE |
最常用的get方法:
requests.get(url,params=None,**kwargs)
- url:
- params:url中的額外參數,字典或字節流格式,可選字段。
- **kwargs:12個控制訪問參數,可選字段(後面會具體講解每個參數的含義)
其他幾個方法如下:
requests.request(method,url,**kwargs)
requests.post(url,data=None,json=None,**kwargs)
requests.head(url,**kwargs)
requests.put(url,data=None,**kwargs)
requests.patch(url,data=None,**kwargs)
requests.delete(url,**kwargs)
PS:這裏要說明一下:
r = requests.request(method='GET', url=url, **kwargs)
r = requests.get(url, **kwargs)
這兩句代碼的意思完全一樣,只是爲了方便,做了一層封裝而已。
2. Requests中兩個重要的對象
r = requests.get(url)
r:是一個Response對象,一個包含服務器資源的對象,Request對象包含爬蟲返回的內容。
.get(url):是一個Request對象,構造一個向服務器請求資源的Request。
PS:這兩個對象指的就是就是HTTP協議中的請求和響應報文。
常見的Response對象的屬性:
屬性 | 說明 |
---|---|
r.status_code | HTTP 請求的返回狀態,200表示連接成功,404表示失敗 |
r.text | HTTP響應內容的字符串形式,即,url對應的頁面內容 |
r.encoding | 從HTTP header中猜測的響應內容的編碼方式 |
r.apparent_encoding | 從內容中分析出的響應內容編碼方式(備選編碼方式) |
r.content | HTTP響應內容的二進制形式 |
r.headers | HTTP響應內容的頭部信息 |
3. **kwargs 控制訪問的參數
**kwargs:控制訪問的參數,均爲可選項
參數 | 說明 |
---|---|
params | 字典或字節序列,作爲參數增加到url中。 |
data | 字典、字節序列或文件對象,作爲Request的內容 ,放在url鏈接對應位置的地方,作爲數據來存儲 |
json | JSON數據格式,作爲Request的內容 |
headers | 字典,HTTP定製頭 |
cookies | 字典或CookieJar,Request中的cookie |
auth | 元組類型,它是支持http認證功能的。 |
files | 字典類型,傳輸文件 |
timeout | 設置超時時間,秒爲單位 |
proxies | 字典類型,設定訪問代理服務器,可以增加登錄認證。(有效地防止對爬蟲的逆追蹤) |
allow_redirects | True/False,默認爲True,表示允許對url進行重定向 |
stream | True/False,默認爲True,獲取內容即下載開關 |
verify | True/False,默認爲True,認證SSL證書開關 |
cert | 保存本地SSL證書路徑的字段 |
這十三個控制訪問參數具體使用如下:
- params
import requests
kv = {'key1': 'one', 'key2': 'two'}
r = requests.request('GET', 'http://python123.io/ws', params=kv)
print(r.request.url) #看看提交的URL變成了什麼
'https://python123.io/ws?key1=one&key2=two'
- data
import requests
key = {'key1':'one', 'key2':'two'}
url = 'http://httpbin.org/put'
r = requests.request('POST', 'http://python123.io/ws', data=key)
# or
r = requests.request('POST', 'http://python123.io/ws', data='FDGDFG') #字符串
- json,一種數據格式。
import requests
kv = {'name': 'youdi', 'role': 'king', 'rank': 'the one'}
url = 'http://httpbin.org/post'
r = requests.request(method='POST', url=url, json=kv)
print(r.text)
{
"args": {},
"data": "{\"role\": \"king\", \"rank\": \"the one\", \"name\": \"youdi\"}", #json格式,其實就是字符串
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "52",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.13.0"
},
"json": {
"name": "youdi",
"rank": "the one",
"role": "king"
},
"origin": "183.60.175.16",
"url": "http://httpbin.org/post"
}
- headers
import requests
url = 'http://httpbin.org/post'
r = requests.request('POST', url)
print(r.request.headers) # 請求頭部信息
# 觀察User-Agent
{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '0'}
#加入headers後
headers = {"User-Agent": "Mozilla/5.0"}
r = requests.request('POST', url, headers=headers)
# 觀察User-Agent
print(r.request.headers)
{'User-Agent': 'Mozilla/5.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '0'}
- cookies
#先獲取百度的cookie
import requests
r = requests.request('GET', 'https://www.baidu.com')
cookie = r.cookies
# cookie類型
print(type(cookie))
<class 'requests.cookies.RequestsCookieJar'>
- auth,用於支持HTTP認證。類似於網頁上登錄填寫賬號密碼的意思~
import requests
# 最簡單的http驗證
from requests.auth import HTTPBasicAuth
r = requests.get('http://httpbin.org/auth', auth=HTTPBasicAuth('user', 'user'))
# r = requests.get('http://httpbin.org/auth', auth=('user', 'user'))
print(r.status_code)
- files
fs = {file: open('data.xls', 'rb')}
# 使用files參數就可以了
r = requests.request('POST','http://httpbin.org/post',files=fs)
- timeout
import requests
from requests.exceptions import ReadTimeout
try:
# 設置必須在500ms內收到響應,不然或拋出ReadTimeout異常
response = requests.get("http://httpbin.org/get", timeout=0.5)
print(response.status_code)
except ReadTimeout:
print('Timeout')
- proxies,字典類型,設定訪問代理服務器,可以增加登錄認證。
import requests
#普通代理
proxies = {
"http": "http://127.0.0.1:1080",
"https": "https://127.0.0.1:1080",
}
# 往請求中設置代理(proxies)
r = requests.get("https://www.taobao.com", proxies=proxies)
print(r.status_code)
# 帶有用戶名和密碼的代理
proxies = {
"http": "http://user:[email protected]:9743/",
}
r = requests.get("https://www.taobao.com", proxies=proxies)
print(r.status_code)
# 設置socks代理,翻牆必備。但是得提前安裝庫:pip install pysocks
proxies = {
'http': 'socks5://127.0.0.1:1080',
'https': 'socks5://127.0.0.1:1080'
}
r = requests.get("https://www.google.com", proxies=proxies)
print(r.status_code)
- allow_redirects,True/False,默認爲True,重定向開關。
r = requests.request('GET','http://httpbin.org/get',allow_redirects=False)
- stream,True/False,默認爲True,獲取內容立即下載開關。
r = requests.request('GET','http://httpbin.org/get/**.txt',stream=False)
- verity,True/False默認Ture,認證ssl證書開關。
# 無證書訪問
r = requests.get('https://www.12306.cn')
# 在請求https時,request會進行證書的驗證,如果驗證失敗則會拋出異常
print(r.status_code)
# 關閉驗證,但是仍然會報出證書警告
r = requests.get('https://www.12306.cn',verify=False)
print(r.status_code)
# 消除關閉證書驗證的警告
from requests.packages import urllib3
# 關閉警告
urllib3.disable_warnings()
r = requests.get('https://www.12306.cn',verify=False)
print(r.status_code)
- cert,本地ssl證書路徑。
# 設置本地證書
r = requests.get('https://www.12306.cn', cert=('/home/youdi/Download/**.crt', '/hone/youdi/.ssh/**.key'))
print(r.status_code)
4. 理解Requests的異常
不是所有請求都能成功的,會有許多異常。
異常 | 說明 |
---|---|
requests.ConnectionError | 網絡連接異常,如DNS查詢失敗,拒絕連接等 |
requests.HTTPError | HTTP錯誤異常 |
requests.URLRequired | URL缺失異常 |
requests.TooManyRedirects | 超過最大重定向次數,產生重定向異常 |
requests.ConnectTimeout | 連接遠程服務器超時異常 |
requests.Timeout | 請求URL超時,產生超時異常 |
import requests
import requests.exceptions
try:
response = requests.get("http://httpbin.org/get", timeout = 0.5)
print(response.status_code)
except requests.ReadTimeout:
print('Timeout') # 超時異常
except requests.ConnectionError:
print('Connection error') # 連接異常
except requests.HTTPError:
print('Error')
5. 理解Response的異常
r.raise_for_status(),如果status_code不是200,產生異常requests.HTTPError。
r.raise_for_status()方法內部判斷r.status_code是否等於200,不需要增加額外的if語句,該語句便於利用try-except進行異常處理。
import requests
import requests.exceptions
url = "https://www.amazon.cn/dp/B00J7E381S?ref_=Oct_DotdV2_PC_2_GS_DOTD_f0f9ddb1&pf_rd_r=269HMTWP7R5ZPFRGY17V&pf_rd_p=8c48638a-3752-448a-8685-5a17153fb132&pf_rd_m=A1AJ19PSB66TGU&pf_rd_s=desktop-2"
try:
r = requests.get(url)
r.raise_for_status()
except requests.HTTPError:
print("error")
#報錯,顯示HTTPError異常
6. Robots協議
網絡爬蟲的限制:
- 來源審查
判斷User-Agent進行限制。檢查來訪HTTP協議頭的User-Agent域,只響應瀏覽器或友好爬蟲。我們可以根據修改User-Agent域,來避免被限制。 - 發佈公告
Robots協議 ,告訴所有的爬蟲,網站的爬取策略,要爬蟲遵守。
形式:在網站根目錄下的robots.txt文件(例如:www.JD.com/robots.txt),告訴想要爬去網站的人,哪些目錄是允許爬取的,哪些是不允許的。
User-Agent:*
Disallow:/
Robots協議語法:*代表所有,/代表根目錄
7.總結
文章對Python的Request庫進行了詳解,爬蟲系列有時間話會一直更新下去。這裏也強烈推薦《中國大學慕課》上北京理工大學嵩天老師的Python爬蟲課,非常好!文章也是根據嵩老師的課程所寫。
本寶才疏學淺,文章如有不當之處,還請多多指教~~ (●′ω`●)