爬蟲必備requests的擴展包總結
這篇文章是偉兄給我的稿子,總結實用、到位。另外,歡迎訪問并關注他的博客:
https://jl-zhenlaixiaowei.blog.csdn.net/
Requests-Cache的安裝與測試
Requests-Cache模塊是requests模塊的一個擴展功能,用于為requests模塊提供持久化緩存支持。如果requests模塊向一個URL發(fā)送重復請求時,Requests-Cache模塊將會自動判斷當前的網(wǎng)絡請求是否產生了緩存。如果已經產生了緩存,就會從緩存中讀取數(shù)據(jù)作為響應內容。如果沒有緩存就會向服務器發(fā)送網(wǎng)絡請求,獲取服務器所返回的響應內容。使用Requests-Cache模塊可以減少網(wǎng)絡資源避免重復請求的次數(shù),這樣可以變相地躲避一些反爬機制。
說 明
無論是否使用了Anaconda,都需要單獨安裝Requests-Cache模塊,因為Anaconda中并不包含該模塊。
Python?3.9.9?(v3.9.9:ccb0e6a345,?Nov?15?2021,?13:29:20)?
[Clang?6.0?(clang-600.0.57)]?on?darwin
>>>import?requests_cache
>>>version?=?requests_cache.__version__
>>>print(version)
0.9.1
緩存的應用
調用install_cache()函數(shù)實現(xiàn)Requests-Cache的請求,語法格式如下:
install_cache(cache_name='cache',?backend=None,?expire_after=None,?allowable_codes=(200,?),?allowable_methods=('GET',?),?session_factory=<class?'requests_cache.core.CachedSession'>,
**backend_options)
Install_cache()函數(shù)中包含了多個參數(shù),每個參數(shù)的含義如下:
§ cache_name: 表示緩存文件的名稱,默認為cache
§ backend: 表示設置緩存的存儲機制,默認為None,表示默認使用sqlite進行存儲
§ expire_after: 表示設置緩存的有效時間,默認為None,表示永久有效
§ allowable_codes:表示設置狀態(tài)碼,默認為200
§ allowable_methods:表示設置請求方式,默認為GET,表示只有GET請求才可以生產緩存
§ session_factory: ?表示設置緩存執(zhí)行的對象,需要實現(xiàn)CachedSession類
§ **backend_options: 如果緩存的存儲方式為sqlite、mongo、redis數(shù)據(jù)庫,該參數(shù)表示設置數(shù)據(jù)庫的連接方式
在使用install_cache()函數(shù)實現(xiàn)請求緩存時,一般情況下時不需要單獨設置任何參數(shù)的,只需要使用默認參數(shù)即可。判斷是否存在緩存的代碼如下:
#_*_coding:utf-8_*_
#?作者??????:liuxiaowei
#?創(chuàng)建時間???:1/30/22 8:32 AM
#?文件??????:判斷緩存是否存在.py
# IDE ?????:PyCharm
#?導入requests_cache模塊
import?requests_cache
#?導入網(wǎng)絡請求模塊
import?requests
#?設置緩存
requests_cache.install_cache()
#?清理緩存
requests_cache.clear()
#?定義測試地址
url?=?'http://httpbin.org/get'
#?第一次發(fā)送網(wǎng)絡請求
r?=?requests.get(url)
#?False表示不存在緩存
print('是否存在緩存:',?r.from_cache)
#?第二次發(fā)送網(wǎng)絡請求
r?=?requests.get(url)
#?True表示存在緩存
print('是否存在緩存:',?r.from_cache)
程序運行結果如下:
是否存在緩存:?False
是否存在緩存:?True
針對反爬措施,在多次請求中設置延時是不錯的選擇。但是如果在第一次請求后生成了緩存,那么第二次請求時就無需設置延時,為此Requests-Cache模塊可以使用自定義鉤子函數(shù)的方式,合理判斷是否需要設置延時操作。示例代碼如下:
#_*_coding:utf-8_*_
#?作者??????:liuxiaowei
#?創(chuàng)建時間???:1/30/22 8:57 AM
#?文件??????:利用鉤子函數(shù)判斷是否需要設置延時.py
# IDE ?????:PyCharm
#?導入Requests_Cache模塊
import?requests_cache
#?導入時間模塊
import?time
#?設置緩存
requests_cache.install_cache()
#?清理緩存
requests_cache.clear()
#?定義鉤子函數(shù)
def?make_throttle_hook(timeout?=?0.1):
????def?hook(response,?*args,?**kwargs):
????????print(response.text)
????????#?判斷沒有緩存時就添加延時
????????if?not?getattr(response,?'from_cache',?False):
????????????print('等待',?timeout,?'秒!')
????????????#?等待指定時間
????????????time.sleep(timeout)
????????else:
????????????#?存在緩存輸出True
????????????print('是否存在請求緩存!',?response.from_cache)
????????return?response
????return?hook
if?__name__?==?'__main__':
????requests_cache.install_cache()
????requests_cache.clear()
????s?=?requests_cache.CachedSession()
????s.hooks?=?{'response':?make_throttle_hook(2)}???#?配置鉤子函數(shù)
????#?模擬發(fā)送第一次網(wǎng)絡請求
????s.get('http://httpbin.org/get')
????#?模擬發(fā)送第二次網(wǎng)絡請求
????s.get('http://httpbin.org/get')
程序運行結果:
第一次運行結果:
{
??"args":?{},?
??"headers":?{
????"Accept":?"*/*",?
????"Accept-Encoding":?"gzip,?deflate",?
????"Host":?"httpbin.org",?
????"User-Agent":?"python-requests/2.27.1",?
????"X-Amzn-Trace-Id":?"Root=1-61f5e91a-5c923abe41da544561b5f400"
??},?
??"origin":?"139.209.219.102",?
??"url":?"http://httpbin.org/get"
}
等待2秒
第二次請求結果
{
??"args":?{},?
??"headers":?{
????"Accept":?"*/*",?
????"Accept-Encoding":?"gzip,?deflate",?
????"Host":?"httpbin.org",?
????"User-Agent":?"python-requests/2.27.1",?
????"X-Amzn-Trace-Id":?"Root=1-61f5e91a-5c923abe41da544561b5f400"
??},?
??"origin":?"139.209.219.102",?
??"url":?"http://httpbin.org/get"
}
二次請求存在緩存
是否存在請求緩存!?True
從以上的運行結果看,通過配置鉤子函數(shù)可以實現(xiàn):在第一次請求時,因為沒有請求緩存所以執(zhí)行了2秒等待延時;第二次請求時則沒有執(zhí)行2秒 延時,并輸出是否存在請求緩存行為True。
說 明
Requests-Cache模塊支持4種不同的存儲機制,分別為money、sqlite、mongoDB以及redid,具體說明如下:
§ memory: 以字典的形式將緩存存儲在內存當中,程序運行完后緩存將被銷毀
§ sqlite: 將緩存存儲在sqlite數(shù)據(jù)庫中
§ mongoDB:將緩存存儲在mongoDB數(shù)據(jù)庫中
§ redis: 將緩存存儲在redis數(shù)據(jù)庫當中
使用Requests-Cache模塊指定緩存不同的存儲機制時,只需要為install_cache()函數(shù)中backend參數(shù)賦值即可,設置方式如下:
#?導入Requests_Cache模塊
import?requests_cache
#?設置緩存為內存的存儲機制
requests_cache.install_cache(backend='memory')
#?設置緩存為sqlite數(shù)據(jù)庫的存儲機制
requests_cache.install_cache(backend='sqlite')
#?設置緩存為mongoDB數(shù)據(jù)庫的存儲機制
requests_cache.install_cache(backend='mongoDB')
#?設置緩存為redis數(shù)據(jù)庫的存儲機制
requests_cache.install_cache(backend='redis')
設置存儲機制為mongoDB與redis數(shù)據(jù)庫時,需要提取安裝對應的操作模塊與數(shù)據(jù)庫。安裝模塊的命令如下:
pip?install?pymongo
pip?install?redis
強大的Requests-HTML模塊
Requests-HTML 模塊是requets模塊的親兄弟,是同一個開發(fā)者所開發(fā)的。Requests-HTML模塊不僅包含了requests模塊中的所有功能,還增加了對JavaScript的支持、數(shù)據(jù)提取以及模擬真實瀏覽器等功能。
使用Requests-HTML模塊實現(xiàn)網(wǎng)絡請求
§ 1、get()請求
通過'pip install requests-html'命令進行模塊的安裝,然后導入Requests-HTML模塊中的HTMLSession類,接著需要創(chuàng)建HTML會話對象,通過會話實例進行網(wǎng)絡請求的發(fā)送,示例代碼如下:
#_*_coding:utf-8_*_
#?作者??????:liuxiaowei
#?創(chuàng)建時間???:1/30/22 3:48 PM
#?文件??????:使用Requests-HTML模塊實現(xiàn)網(wǎng)絡請求.py
# IDE ?????:PyCharm
#?導入HTMLSession類
from?requests_html?import?HTMLSession
#?創(chuàng)建HTML會話對象
session?=?HTMLSession()
#?定義請求地址
url?=?'http://news.youth.cn/'
#?發(fā)送網(wǎng)絡請求
r?=?session.get(url)
#?打印網(wǎng)絡請求的URL地址
print(r.html)
程序運行結果如下:
'http://news.youth.cn/'>
§ 2、post()請求
在實現(xiàn)網(wǎng)絡請求時,POST請求也是一種比較常見的請求方式,使用Requests-HTML實現(xiàn)POST請求與requests的實現(xiàn)方法類似都需要單獨設置表單參數(shù)data,不過它也是需要通過會話實例進行網(wǎng)絡請求的發(fā)送,示例代碼如下:
#_*_coding:utf-8_*_
#?作者??????:liuxiaowei
#?創(chuàng)建時間???:1/30/22 4:44 PM
#?文件??????:post()請求.py
# IDE ?????:PyCharm
#?導入HTMLSession類
from?requests_html?import?HTMLSession
#?創(chuàng)建HTML會話對象
session?=?HTMLSession()
#?模擬表單登錄的數(shù)據(jù)
data?=?{'user':'admin',?'password':123456}
#?發(fā)送POST請求
r?=?session.post('http://httpbin.org/post',?data?=?data)
#?判斷請求是否成功
if?r.status_code?==?200:
????print(r.text)
程序運行結果如下:
{
??"args":?{},?
??"data":?"",?
??"files":?{},?
??#?表單數(shù)據(jù)
??"form":?{
????"password":?"123456",?
????"user":?"admin"
??},?
??"headers":?{
????"Accept":?"*/*",?
????"Accept-Encoding":?"gzip,?deflate",?
????"Content-Length":?"26",?
????"Content-Type":?"application/x-www-form-urlencoded",?
????"Host":?"httpbin.org",?
????#?User-Agent對應的值
????"User-Agent":?"Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_12_6)?AppleWebKit/603.3.8?(KHTML,?like?Gecko)?Version/10.1.2?Safari/603.3.8",?
????"X-Amzn-Trace-Id":?"Root=1-61f6509d-56a381b4543229480fe07e56"
??},?
??"json":?null,?
??"origin":?"139.209.219.102",?
??"url":?"http://httpbin.org/post"
}
從以上的運行結果中,不僅可以看到form所對應的表單內容,還可以看到User-Agent所對應的值,并不是像requests模塊發(fā)送網(wǎng)絡請求時返回的默認值(python-requests/2.27.1),而是一個真實的瀏覽器請求頭信息,這與requests模塊所發(fā)送的網(wǎng)絡請求有著細小的改進。
§ 3、修改請求頭信息
說到請求頭信息,Requests-HTML模塊是可通過指定headers參數(shù)來對默認的瀏覽器請求頭信息進行修改的,修改請求頭信息的關鍵代碼如下:
ua?=?{'User-Agent':'Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/97.0.4692.99?Safari/537.36?Edg/97.0.1072.76'
}
r?=?session.post('http://httpbin.org/post',?data?=?data,?headers?=?ua)
§ Requests-HTML模塊中添加了UserAgent類,使用該類可以實現(xiàn)隨機生成請求頭。示例代碼如下:
#_*_coding:utf-8_*_
#?作者??????:liuxiaowei
#?創(chuàng)建時間???:1/30/22 9:06 PM
#?文件??????:生成隨機請求頭信息.py
# IDE ?????:PyCharm
#?導入HTMLSession類
from?requests_html?import?HTMLSession,?UserAgent
#?創(chuàng)建HTML會話對象
session?=?HTMLSession()
#?創(chuàng)建隨機請求頭
ua?=UserAgent().random
r?=?session.get('http://httpbin.org/get',?headers?=?{'user-agent':?ua})
#?判斷請求是否成功
if?r.status_code?==?200:
????#?以文本形式打印返回結果
????print(r.text)
程序運行結果如下:
{
??"args":?{},?
??"headers":?{
????"Accept":?"*/*",?
????"Accept-Encoding":?"gzip,?deflate",?
????"Host":?"httpbin.org",?
????#?請求頭信息
????"User-Agent":?"Mozilla/5.0?(X11;?Ubuntu;?Linux?x86_64;?rv:17.0)?Gecko/20100101?Firefox/17.0.6",?
????"X-Amzn-Trace-Id":?"Root=1-61f69454-0b37eb40198f0f4b237fc7e8"
??},?
??"origin":?"139.209.219.102",?
??"url":?"http://httpbin.org/get"
}
{
??"args":?{},?
??"headers":?{
????"Accept":?"*/*",?
????"Accept-Encoding":?"gzip,?deflate",?
????"Host":?"httpbin.org",?
????#?請求頭信息
????"User-Agent":?"Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_8_2)?AppleWebKit/537.17?(KHTML,?like?Gecko)?Chrome/24.0.1309.0?Safari/537.17",?
????"X-Amzn-Trace-Id":?"Root=1-61f693aa-0d20428a3a73766723017536"
??},?
??"origin":?"139.209.219.102",?
??"url":?"http://httpbin.org/get"
}
備注
以上運行是在Anaconda的Jupiter notebook 下運行。Pycharm 報錯,應該是解釋器的問題。
數(shù)據(jù)的提取
以往使用requests模塊實現(xiàn)爬蟲程序時,還需要為其配置一個解析HTML代碼的搭檔。Requests-HTML模塊對此進行了一個比較大的升級,不僅支持CSS選擇器還支持XPath的節(jié)點提取方式。
? 1、CSS選擇器
CSS選擇器中需要使用HTML的find()方法,該方法中包含5個參數(shù),其語法格式與參數(shù)含義如下:
find(selector:str='*',?containing:_Containing=None,?clean:bool=False,first:bool=False,_encoding:str=None)
§ selector: 使用CSS選擇器定位網(wǎng)頁元素
§ containing:通過指定文本獲取網(wǎng)頁元素
§ clean:是否清除HTML中的
