文章目錄
寫在前面
【python爬蟲基礎入門】系列是對python爬蟲的一個入門練習實踐,旨在用最淺顯易懂的語言,總結最明瞭,最適合自己的方法,本人一直堅信,總結纔會使人提高
一.HTTP協議
使用python爬蟲是建立在HTTP協議之上的,何爲HTTP協議呢?
1. HTTP協議的框架
用比較容易理解的話來說,HTTP協議是一種超文本傳輸協議,是一個基於“請求與響應”模式的、無狀態的應用層協議
- 請求和響應:簡單來說就是用戶對服務器發起請求,服務器對用戶的請求作出響應:
- 無狀態:用戶的第一次請求和第二次請求之間沒有必然的聯繫,
- 應用層協議:表示該協議工作在TCP協議之上
此外HTTP協議將使用URL作爲定位網路資源的標識,其URL格式如http://host[:port][path]
- host: 合法的Internet主機域名或者IP地址
- port:端口號,如果不寫,默認缺省端口爲80
- path:請求資源的內部路徑
HTTP url
實例
- http://www.baidu.com
- http://234.190.111.148/list //list目錄下的相關資源
HTTP中的ur
l通過HTTP協議存取資源的Internet路徑,一個url
對應的是一個數據資源。類似於在自己電腦上各個目錄下的文件 ,只不過這裏的資源是放在網上的服務器中
2. HTTP協議對資源的操作
HTTP協議對資源的操作如下,requests庫的各種方法是依託於HTTP的各種資源操作。
方法 | 說明 |
---|---|
GET | 請求獲取URL位置的資源 |
HEAD | 請求獲取URL位置資源的頭部信息 |
POST | 請求向URL位置的資源後面追加新的數據 |
PUT | 請求向URL位置的資源儲存一個新的資源,將覆蓋原有的資源 |
PATCH | 請求局部更新URL位置的資源,即改變該處資源的一部分(更新部分內容,更節省帶寬) |
DELETE | 請求刪除URL位置存儲的資源 |
3. 用戶對HTTP協議的操作
- 用戶想通過url獲取資源
- 使用GET或者HEAD方法
- 用戶想將自己的資源放在URL位置上
- 使用POST或者PATCH或者PUT方法
- 用戶想刪掉這個URL上的資源
- 使用DELETE方法
綜上來看,HTTP協議是網絡傳輸協議的基本,也是python中requests庫的爬取操作的基本,更好的理解HTTP協議可以更清楚的理解requests爬蟲
二.requests庫的安裝
python中的requests庫用於對特定的網頁進行訪問抓抓取操作,是python功能強大的一個庫,常常應用於特定靜態網頁的數據抓取。使用pip
工具在命令行中輸入安裝request庫
pip install requests
三.requests庫的7個主要使用方法
requests庫中包含有七個主要的方法,其中requests.request()
爲主方法,其他的六種方法如get,head
方法等等等均是對requests.request()
的封裝使用。在使用的過程中,可以更具特定的需要方便選擇主方法或者封裝的方法,七種方法如下
方法 | 說明 |
---|---|
ruquests.request() |
構造一個請求,支撐一下各種方法的基礎方法 |
ruquests.get() |
獲取html網頁的主要方法,對應於http的get(最常用) |
ruquests.head() |
獲取html網頁頭信息的方法,對應於http的head(最常用) |
ruquests.post() |
向html網頁提交post請求的方法,對應於http的post |
ruquests.put() |
向html網頁提交put請求的方法,對應於http的put |
ruquests.patch() |
向html網頁提交局部的修改請求,對應於http的patch |
ruquests.delete() |
想html網頁提交刪除請求,對應於http的delete |
1.方法的解析
這裏以主方法request方法爲例子如下
ruquests.request(method,url,**kwargs)
這裏包含有三個參數method,url,**kwargs
- method:請求方式對應GET/HEAD/POST/PUT/PATCH/OPPTIONS七種方法,調用格式爲’GET’
- url:獲取的鏈接
- **kwargs:控制訪問的參數,均爲可選擇項,共13個
其中,**kwargs
包含params,data,json,headers,cookies,auth,files,timeout,proxies,allow_redirects,stream,verify,cert
13個參數,參數使用說明如下
-
params:字典或者字節序列,作爲參數增加到url中(常用與請求服務器特定資源)
-
kv = {'hey1':'value1', 'key2':'value2'} r = requests.request('GET','http://python123.io/ws', params=kv) print('r.url') >>>http://python123.io/ws?key1=value1&key2=value2 # ? 號後面纔是要跟上的內容
-
data:字典、字節序列或者文件對象,作爲Request的內容(常作爲向服務器提交資源使用)
-
kv = {'hey1':'value1', 'key2':'value2'} r = requests.request('POST','http://python123.io/ws', data=kv) # 或者直接使用字段 body='主題內容' r = requests.request('POST','http://python123.io/ws', data=body)
-
json:JSON格式的數據,作爲Request的內容(常用於向服務器提交)
-
r = requests.request('POST','http://python123.io/ws', json=kv)
-
headers:字典,HTTP定製頭(常用於模擬遊覽器)
-
hd = {'user-aget':'Chrome/10'} r = requests.request('POST','http://python123.io/ws', hheader=hd)
-
cookies:字典或者CookieJar,Requests中的cookie,在不同用戶遊覽器的特定頁面中有特定的值
-
auth:元祖,支持HTTP認證功能
-
files:字典類型,傳輸文件(常用於向服務器傳輸文件使用)
-
fs = {'file' : open('data.xls','rb')} r = requests.request('POST','http://python123.io/ws', files=fs)
-
timeout:設定超時單位,秒爲單位(常用於服務器請求)
-
r = requests.request('GET','http://python123.io/ws', timeout=10)
-
proxies:字典類型,設定訪問代理服務器,可以增加登陸認證(常用於隱藏原ip地址)
-
pxs = {'http': 'http://user:pass@10/.10.10.1:1234' 'https': 'https://10.10.10.1:4321'} r = requests.request('GET','http://python123.io/ws', proxies=pxs)
- allow_redirects:重定向開關,默認爲開啓True,
- stream:獲取內容立即下載開關,默認爲開啓True
- verify:認證SSL證書開關,默認爲開啓True
- cert:本地SSL證書路徑
request方法是最基本的方法,其他的類似於get方法等都是基於Request方法之上的一種封裝形式
2.方法的使用
在網頁請求中,常常使用get,head,post
三種方法
a. get方法使用
import requests
r = requests.get(url) # 獲取網頁網址
print(r.status_code) # 請求狀態碼
r.encoding = 'utf-8' # 設置編碼
r.text # 將打印輸出
這樣的r
作爲Response
返回的對象,包含從服務器返回的所有相關資源
-
requests.get方法的完整使用
-
requests.get(url,params=None,**kwargs)
url
: 指定頁面的鏈接params
: url中的額外參數,字典或者字節流格式,爲可選擇項**kwargs
:12個控制訪問的參數
Response對象的屬性表如下
屬性 | 說明 |
---|---|
r.status_code |
http請求的返回狀態碼,200表示連接成功,404或者其他字符表示連接失敗 |
r.text |
打印http響應內容的字符串形式,即爲url對應的頁面內容 |
r.encoding |
從http的header中猜測的響應內容的編碼方式 |
r.apparent_encoding |
從內容中分析出的響應內容編碼方式(備選編碼方式) |
r.content |
http響應內容的二進制形式 |
需要注意的是
r.encoding
:使用的http協議中charset
的默認編碼格式,通常爲ISO-8859-1
r.apparent_encoding
:將會根據網頁內容分析出可讀的編碼方式,通常爲UTF-8
Response對象屬性的基本流程
- 首先使用
r.status_code
來檢查返回的Response
對象的返回狀態碼- 若返回200(可使用
r.text
,r.encoding
,r.apparent_encoding
,r.content
來解析返回的內容) - 若返回404或者其他編碼。則訪問失敗
- 若返回200(可使用
b. head方法的使用
用head方法來獲取url中的頭部信息,應用如下
r = requests.head(url,**kwargs) # 獲取頭部信息
r.headers # 輸出頭部信息
c. post方法的使用
post方法可以對請求向URL位置的資源後面追加新的數據,應用如下
r = requests.post(url,**kwargs) # 模版
# 如下
payload = {'key1':'valu1', 'key2':'value2'} # 創建一個字典
# 向URL POST一個字典,自動編碼爲一個form表單
r = requests.post('http://httpbin.org/post',data = payload) # 提交修改
print(r.text) # 打印追加後的內容
如果不提交一個字典,只是傳入一個數據,如data,這樣將會自動傳入一個數據量,如下
r = requests.post('http://httpbin.org/post',data = 'ABC') # 提交修改
print(r.text) # 打印追加後的內容
3. requests庫的異常處理
常用的requests
的異常處理如下
異常 | 說明 |
---|---|
ruquests.ConnectionError | 網絡連接錯誤異常,如DNS查詢失敗、拒絕連接等 |
ruquests.HTTPError | HTTP錯誤異常 |
ruquests.URLRequired | URL缺失異常 |
ruquests.TooManyRedirects | 超過最大重定向次數,產生重定向異常 |
ruquests.ConnectTimeout | 連接遠程服務器超時異常(僅僅爲與遠程服務器連接過長) |
ruquests.Timeout | 請求URL超時,產生超時異常(獲得內容的整個過程) |
requests
庫中對於異常處理的方法調用
異常方法 | 說明 |
---|---|
r.raise_for_status() | 此方法將檢測返回狀態碼是否是200,如果不是200,則產生ruquests.HTTPError異常 |
四.爬取網頁的通用代碼框架
在爬取網頁的時候需要我們搭建好一套流程,如同一套框架,清晰的框架可以使得在爬取數據的過程中,更容易檢測錯誤。爬取原聲靜態網頁框架可參照如下
import requests
def getHTMLText(url):
try:
r = requests.get(url,timeout = 30)
r.raise_for_status() # 檢測返回狀態碼,反之則報錯
r.encoding = r.apparent_encoding
return r.text # 返回獲取網頁的內容
except:
return '產生異常'
# 主函數
if __name__ == "__main__":
url = 'http://www.baidu.com'
print(getHTMLText(url))
五.requests庫爬蟲實例
1. 對京東商品頁面的爬取
將遊覽器網址url
設置爲https://itm.jd.com/2967929.html
使用Request庫獲取商品頁面信息,具體代碼如下
import requests
url = 'https://item.jd.com/2967929.html'
kv = {'user-agent': 'Mozilla/5.0'} # 加入遊覽器頭部信息,隱藏頭
try:
r = requests.get(url,header=kv)
r.raise_for_status()
r.encoding = r.appraent_encoding
printf(r.txt[:1000]) # 限定顯示前1000個字符
expect:
print('爬取出錯')
2. 百度/360搜索關鍵字的提交
- 百度的關鍵字接口
http://www,baidu.com/s?wd=keyword
- 360的搜索關鍵字接口
http://www.so.com/s?q=keyword
代碼如下
import requests
'''
使用requests庫使用百度進行關鍵字搜索
'''
keyword = "Python" # 要搜索的關鍵字
try:
kv = {'wd':keyword}
url = 'http://www.baidu.com/s'
r = requests.request('Get',url,params=kv)
# r = requests.get(url,params=kv) # 也可用使用這樣的做法
print(r.request.url)
r.raise_for_status()
print(len(r.text))
except:
print('something wrong!')
3. 網絡圖片的爬取
使用requests庫在特定的網頁中進行網絡圖片的爬取,具體代碼如下
# -*- coding: utf-8 -*-
# @Time : 2020/4/14 22:08
# @Author: 哦嚯嚯哦
# @File : Demo3.py
# @tool : PyCharm
import requests
import os
'''
使用requests庫在特定的網址獲取圖片,並保存在本地文件夾
'''
kv = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36',
'Referer': 'https://www.baidu.com/' # 請求防盜鏈,用於請求網站的反爬
}
url = 'https://i.loli.net/2020/05/16/nwGVPKSbtToYOac.jpg' # 圖片網址
root = 'F://User_Desktop/py_test/' # 保存路徑
path = root + url.split('/')[-1] # 使用圖片的最後幾個字節作爲文件名存儲
try:
if not os.path.exists(root):
os.mkdir(root)
if not os.path.exists(path):
r = requests.get(url, headers=kv)
with open(path,'wb') as f: # 以二進制方式寫入
f.write(r.content)
r.close()
print('文件保存成功')
else:
print('文件已經存在')
except:
print('something wrong!')
將上述代碼改進加入循環爬取可以實現批量定向爬取網站圖片,效果的話,可以自己嘗試下,這裏就不予展示了。
六.網絡爬蟲的正確使用方法
1. 網絡爬蟲的規模分類
根據使用網絡爬蟲的功能的不同,尺寸的不同,將網絡爬蟲分爲三個類
- 小規模:
- 數據量小,對爬取速度不敏感
- 主要用於爬取特定的網頁
- 主要使用Requests庫
- 中規模:
- 數據量較大,爬取速度叫敏感
- 主要用於爬取網站,或者爬取一系列的網站,如爬取攜程上的火車票數據
- 主要使用Scrapy庫
- 大規模
- 搜索引擎級別
- 用於爬取全網
- 需要定製開發
2. 網絡爬蟲的風險
- 知識 產權的風險
- 用戶隱私的泄露
- 服務器的騷然問題(加重對網站服務器的負擔量)
3. Robots協議
該協議作爲網絡爬蟲的一種標準,內嵌於網站中,存在於網站根目錄下的robots.txt文件中,告知網絡爬蟲哪些頁面可以抓取,哪些不允許被抓取
Robots協議的基本語法
# *通配符代表素有,/表示根目錄
User-Agent: *
Disallow: /
Robots協議的網站舉例
https://www.baidu.com/robots.txt
https://www.csdn.net/robots.txt
Robots協議的使用方法,在編寫網絡爬蟲的時候,應當做到以下幾點
- 編寫自動或者人工識別robots.txt,再進行爬取
- 類人行爲的網站訪問,可以不用參考robots.txt協議
雖然規則已經定在哪裏,但是使用爬蟲的時候還是要將規則牢記於心,違法犯罪的事情千萬不能做。
七.結語
有句話說的好,“爬蟲學的好,監獄蹲到老”(當然這只是開玩笑的😄),使用爬蟲需要遵循一定的規則,但只要正確使用,爬蟲還是很好玩滴,(富強,民主,和諧)
八.參考
- 中國大學MOOC