python反反爬蟲技術(shù)限制連續(xù)請求時(shí)間處理
前言
一般的反爬措施是在多次請求之間增加隨機(jī)的間隔時(shí)間,即設(shè)置一定的延時(shí)。但如果請求后存在緩存,就可以省略設(shè)置延遲,這樣一定程度地縮短了爬蟲程序的耗時(shí)。
下面利用requests_cache實(shí)現(xiàn)模擬瀏覽器緩存行為來訪問網(wǎng)站,具體邏輯如下:存在緩存,就直接走,不存在緩存,就停一下再走
示例代碼
用勾子函數(shù)根據(jù)緩存行為設(shè)置訪問時(shí)間
import requests_cacheimport timerequests_cache.install_cache() ? #默認(rèn)按照瀏覽器的緩存進(jìn)行 requests_cache.clear() def make_throttle_hook(timeout=0.1): ? ? def hook(response, *args, **kwargs): ? ? ? ? print(response.text) ? ? ? ? ? # 判斷沒有緩存時(shí)就添加延時(shí) ? ? ? ? if not getattr(response, 'from_cache', False): ? ? ? ? ? ? ? ? print(f'Wait {timeout} s!') ? ? ? ? ? ? ? ?time.sleep(timeout) ? ? ? ?else: ? ? ? ? ? ? ? print(f'exists cache: {response.from_cache}') ? ? ? ?return response ? ?return hookif __name__ == '__main__': ? ? requests_cache.install_cache() ? ? requests_cache.clear() ? session = requests_cache.CachedSession() # 創(chuàng)建緩存會話 ? ? session.hooks = {'response': make_throttle_hook(2)} # 配置鉤子函數(shù) ? ? print('first requests'.center(50,'*')) ? ? session.get('http://httpbin.org/get') ? print('second requests'.center(50,'*')) ? ? session.get('http://httpbin.org/get')
有關(guān)requests_cache的更多用法,參考下面requests_cache說明
爬蟲相關(guān)庫
1. 爬蟲常用的測試網(wǎng)站:httpbin.org
httpbin.org 這個(gè)網(wǎng)站能測試 HTTP 請求和響應(yīng)的各種信息,比如 cookie、ip、headers 和登錄驗(yàn)證等,且支持 GET、POST 等多種方法,對 web 開發(fā)和測試很有幫助。它用 Python + Flask 編寫,是一個(gè)開源項(xiàng)目。
2. requests-cache
requests-cache,是 requests 庫的一個(gè)擴(kuò)展包,利用它可以非常方便地實(shí)現(xiàn)請求的緩存,直接得到對應(yīng)的爬取結(jié)果。
作用和使用場景
1.在爬取過程中,它可以根據(jù)瀏覽器的緩存機(jī)制來選擇緩存內(nèi)容。從請求行為上看與瀏覽器更加相似,起到反反爬的效果。
2.另外,還可以自定義緩存機(jī)制,在爬蟲項(xiàng)目中,優(yōu)化性能。
requests-cache庫只能對requests的請求實(shí)現(xiàn)緩存功能,而且requests要以session方式進(jìn)行請求。單獨(dú)的requests.get、requests.post 不能被緩存。
requests
使用方法
安裝:
$ pip install requests-cache
與普通的代碼比較
在爬取一個(gè)域名下的多個(gè)url時(shí),使用requests.session.get或requests.session.post會比單純的requests.get、requests.post更高效。因?yàn)樗唤⒘艘粋€(gè)會話,并在上面做多次請求。同時(shí)還支持登錄信息cookie等的傳遞。
下面比較一下緩存代碼的寫法 沒有緩存的代碼:
普通的requests session爬取
import requests import time start = time.time() session = requests.Session() for i in range(10): session.get('http://httpbin.org/delay/1') print(f'Finished {i + 1} requests') end = time.time() print('Cost time', end - start)
該代碼是訪問了httpbin.org網(wǎng)站,該網(wǎng)站會解析delay/1,在1秒后返回。
有緩存的代碼:
帶緩存的requests session爬取
import requests_cache #pip install requests_cache import time start = time.time() session = requests_cache.CachedSession('demo_cache') for i in range(10): session.get('http://httpbin.org/delay/1') print(f'Finished {i + 1} requests') end = time.time() print('Cost time', end - start)
為原有代碼微創(chuàng)式添加緩存功能
只需要添加一句requests_cache.install_cache('demo_cache')即可。
微創(chuàng)式添加緩存功能
import requests_cache #pip install requests_cache requests_cache.install_cache('demo_cache')#demo_cache.sqlite 做緩存 import requests import time start = time.time() session = requests.Session() for i in range(10): session.get('http://httpbin.org/delay/1') print(f'Finished {i + 1} requests') end = time.time() print('Cost time', end - start)
緩存的清空和識別
如果需要清空緩存,可以調(diào)用:requests_cache.clear() # 清空緩存代碼
通過res.from_cache可以判斷該值是否是緩存值:
import requests_cache import requests requests_cache.install_cache() # 設(shè)置緩存 requests_cache.clear() # 清空緩存 url = 'http://httpbin.org/get' res = requests.get(url) print(f'cache exists: {res.from_cache}') # cache exists: False # 不存在緩存 res = requests.get(url) print(f'exists cache: {res.from_cache}') # exists cache: True # 存在緩存
自定義設(shè)置緩存的形式
requests_cache.install_cache默認(rèn)的方式是與瀏覽器的緩存行為一致的。如果要自定義可以先了解該函數(shù)的參數(shù):
requests_cache.install_cache定義
requests_cache.install_cache( cache_name='cache', backend=None, expire_after=None, allowable_codes=(200,), allowable_methods=('GET',), filter_fn=< function <lambda> at 0x11c927f80>, session_factory=< class 'requests_cache.core.CachedSession'>, **backend_options,)
該參數(shù)說明如下: - cache_name:緩存文件名稱。
- backend:設(shè)置緩存的存儲機(jī)制,默認(rèn)使用sqlite進(jìn)行存儲。
支持四種不同的存儲機(jī)制,分別為memory、sqlite、mongoDB、redis。在設(shè)置存儲機(jī)制為mongoDB、redis時(shí)需要提前安裝對應(yīng)的模塊。pip install pymongo; pip install redies。 - memory:以字典的形式將緩存存儲在內(nèi)存當(dāng)中,程序運(yùn)行完以后緩存將被銷毀
- sqlite:將緩存存儲在sqlite數(shù)據(jù)庫中
- mongoDB:將緩存存儲在mongoDB數(shù)據(jù)庫中
- redis:將緩存存儲在redis中
- expire_after:設(shè)置緩存的有效時(shí)間,默認(rèn)永久有效。
- allowable_codes:設(shè)置狀態(tài)碼。
- allowable_methods:設(shè)置請求方式,默認(rèn)get,表示只有g(shù)et請求才可以生成緩存。
- session_factory:設(shè)置緩存執(zhí)行的對象,需要實(shí)現(xiàn)CachedSession類。
- **backend_options:如果緩存的存儲方式為sqlit、mongo、redis數(shù)據(jù)庫,該參數(shù)表示設(shè)置數(shù)據(jù)庫的連接方式。
自定義設(shè)置緩存的例子1:設(shè)置緩存文件類型
設(shè)置緩存文件類型的代碼如下:
#設(shè)置緩存:任選其一 requests_cache.install_cache('demo_cache')#demo_cache.sqlite 做緩存 #demo_cache文件夾做緩存,刪除及表示清空緩存 requests_cache.install_cache('demo_cache', backend='filesystem') #緩存文件夾便會使用系統(tǒng)的臨時(shí)目錄,而不會在代碼區(qū)創(chuàng)建緩存文件夾。 requests_cache.install_cache('demo_cache', backend='filesystem', use_temp=True) #緩存文件夾便會使用系統(tǒng)的專用緩存文件夾,而不會在代碼區(qū)創(chuàng)建緩存文件夾 requests_cache.install_cache('demo_cache', backend='filesystem', use_cache_dir=True) #Redis ,需要安裝redis-py pip install redies backend = requests_cache.RedisCache(host='localhost', port=6379) requests_cache.install_cache('demo_cache', backend=backend)
其他不同格式:
MongoDB 安裝pymongo pip install pymongo;
調(diào)用requests_cache.MongoCache 保存為’mongodb’
gridfs 安裝pymongo
調(diào)用requests_cache.GridFSCache 保存為’gridfs’
DynamoDB boto3 調(diào)用requests_cache.DynamoDbCache 保存為’dynamodb’
Memory 以字典的形式將緩存存儲在內(nèi)存當(dāng)中,程序運(yùn)行完以后緩存將被銷毀 調(diào)用requests_cache.BaseCache 保存為’memory’
自定義設(shè)置緩存的例子2:設(shè)置緩存保存內(nèi)容
具體例子代碼如下:
import time import requests import requests_cache #只緩存post requests_cache.install_cache('demo_cache2', allowable_methods=['POST']) #只緩存200返回值的請求 requests_cache.install_cache('demo_cache2', allowable_codes=(200,))
只緩存200返回值的請求
設(shè)置緩存的過期時(shí)間:
#site1.com 的內(nèi)容就會緩存 30 秒,site2.com/static 的內(nèi)容就永遠(yuǎn)不會過期 urls_expire_after = {'*.site1.com': 30, 'site2.com/static': -1} requests_cache.install_cache( 'demo_cache2', urls_expire_after=urls_expire_after)
在響應(yīng)頭中,瀏覽器會根據(jù)cache_control參數(shù)來確定是否保存緩存,在設(shè)置requests_cache緩存時(shí),可以對cache_control參數(shù)設(shè)置,使其保存瀏覽器不需要保存的內(nèi)容。
# 保存頭中,cache_control設(shè)為不保存的請求 requests_cache.install_cache('demo_cache3', cache_control=True) start = time.time() session = requests.Session() for i in range(10): session.get('http://httpbin.org/delay/1') print(f'Finished {i + 1} requests') end = time.time() print('Cost time for get', end - start) start = time.time() for i in range(10): session.post('http://httpbin.org/delay/1') print(f'Finished {i + 1} requests') end = time.time() print('Cost time for post', end - start)
在 Request Headers 里面加上了 Cache-Control 為 no-store,這樣的話,即使我們聲明了緩存那也不會生效
session.get('http://httpbin.org/delay/1', headers={ 'Cache-Control': 'no-store' } )
以上就是python反反爬蟲技術(shù)限制連續(xù)請求時(shí)間處理的詳細(xì)內(nèi)容,更多關(guān)于python反反爬蟲連續(xù)請求限制的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Django csrf 驗(yàn)證問題的實(shí)現(xiàn)
csrf是通過偽裝來自受信任用戶的請求來利用受信任的網(wǎng)站。這篇文章主要介紹了Django csrf 驗(yàn)證問題的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10使用Python和Scribus創(chuàng)建一個(gè)RGB立方體的方法
這篇文章主要介紹了使用Python和Scribus創(chuàng)建一個(gè)RGB立方體的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python OpenCV 針對圖像細(xì)節(jié)的不同操作技巧
這篇文章主要介紹了Python OpenCV 針對圖像細(xì)節(jié)的不同操作,包括圖像像素的說明,圖像屬性信息的獲取與修改以及圖像通道的知識(包括拆分通道和合并通道),需要的朋友可以參考下2021-08-08