使用過(guò)代理IP的同學(xué)應(yīng)該都知道拂封,即使是同一個(gè)IP,訪問(wèn)不同網(wǎng)站蔬芥,可用性和速度都可能大不相同梆靖。因此,根據(jù)實(shí)際使用情況編寫(xiě)特定站點(diǎn)的代理校驗(yàn)器是非常必要的笔诵。本文介紹擴(kuò)展haipproxy的校驗(yàn)器方法返吻,為了方便闡述,下面我們以zhihu.com為例進(jìn)行說(shuō)明嗤放。
1.在settings.py中添加zhihu
校驗(yàn)器對(duì)應(yīng)的temp queue
思喊、validated queue
壁酬、ttl queue
及speed queue
次酌。temp queue
的作用是作為臨時(shí)隊(duì)列存儲(chǔ)下一次定時(shí)校驗(yàn)的任務(wù),validated queue
是已經(jīng)校驗(yàn)過(guò)的任務(wù)舆乔,記錄了對(duì)應(yīng)代理IP的打分(成功率)岳服,ttl queue
是對(duì)應(yīng)代理IP最近一次的校驗(yàn)時(shí)間,speed queue
記錄的是對(duì)應(yīng)代理IP最近一次校驗(yàn)的響應(yīng)速度希俩,后面三個(gè)隊(duì)列都會(huì)作為客戶端獲取代理IP需要考慮的因素吊宋。這里我將四者分別設(shè)置為
TEMP_ZHIHU_QUEUE = 'haipproxy:zhihu:temp'
VALIDATED_ZHIHU_QUEUE = 'haipproxy:validated:zhihu'
TTL_ZHIHU_QUEUE = 'haipproxy:ttl:zhihu'
SPEED_ZHIHU_QUEUE = 'haipproxy:speed:zhihu'
2.將上一步的queue
配置到rules.py中對(duì)應(yīng)的maps中
VALIDATOR_TASKS = [
{
'name': 'zhihu',
'task_queue': TEMP_ZHIHU_QUEUE,
'resource': VALIDATED_ZHIHU_QUEUE,
'internal': 20,
'enable': 1,
},
]
TEMP_TASK_MAPS = {
# temp task maps 中init queue必須存在
'init': INIT_HTTP_QUEUE,
'zhihu': TEMP_ZHIHU_QUEUE
}
SCORE_MAPS = {
'zhihu': VALIDATED_ZHIHU_QUEUE
}
TTL_MAPS = {
'zhihu': TTL_ZHIHU_QUEUE
}
SPEED_MAPS = {
'zhihu': SPEED_ZHIHU_QUEUE
}
3.在校驗(yàn)器模塊添加知乎校驗(yàn)器爬蟲(chóng),具體流程如下
- 新建校驗(yàn)器爬蟲(chóng)文件
zhihu.py
,在其中添加校驗(yàn)具體邏輯
from config.settings import (
TEMP_ZHIHU_QUEUE, VALIDATED_ZHIHU_QUEUE,
TTL_ZHIHU_QUEUE, SPEED_ZHIHU_QUEUE)
# ValidatorRedisSpider提供了分布式父類(lèi)爬蟲(chóng)
from ..redis_spiders import ValidatorRedisSpider
# BaseValidator提供了基本的請(qǐng)求錯(cuò)誤處理颜武,但是業(yè)務(wù)相關(guān)邏輯錯(cuò)誤需要自己實(shí)現(xiàn)
from .base import BaseValidator
class ZhiHuValidator(BaseValidator, ValidatorRedisSpider):
# scrapy爬蟲(chóng)名璃搜,必須設(shè)置且不能與已知的重復(fù)
name = 'zhihu'
# 需要驗(yàn)證的URL,建議選擇一個(gè)穩(wěn)定且有代表意義的url鳞上,數(shù)據(jù)結(jié)構(gòu)是一個(gè)list
urls = [
'https://www.zhihu.com/question/47464143'
]
# 下面四個(gè)屬性必須設(shè)置这吻,并且與maps中的一致
task_queue = TEMP_ZHIHU_QUEUE
score_queue = VALIDATED_ZHIHU_QUEUE
ttl_queue = TTL_ZHIHU_QUEUE
speed_queue = SPEED_ZHIHU_QUEUE
# 判斷success_key是否在響應(yīng)內(nèi)容中,從而判斷IP是否正常篙议,默認(rèn)為''唾糯,表示正常
success_key = ''
- 在HttpBinInitValidator的
https_tasks
中添加zhihu
任務(wù)
class HttpBinInitValidator(BaseValidator, ValidatorRedisSpider):
"""This validator do initially work for ip resources"""
name = 'init'
urls = [
'http://httpbin.org/ip',
'https://httpbin.org/ip',
]
use_set = False
task_queue = INIT_HTTP_QUEUE
https_tasks = ['https', 'zhihu']
http_tasks = ['http']
- 常規(guī)校驗(yàn)器到上一步就完成了怠硼,如果有和業(yè)務(wù)相關(guān)的驗(yàn)證邏輯,比如在IP被封的時(shí)候返回的狀態(tài)碼仍是
200
移怯。這個(gè)時(shí)候依靠BaseValidator的parse_error
方法是不夠的香璃。因?yàn)?code>BaseValidator只會(huì)篩選不能用的代理IP。這里不能用的標(biāo)準(zhǔn)是HTTP狀態(tài)碼是非2xx
或者3xx
舟误。但是某些網(wǎng)站如微博和知乎葡秒,在封IP后仍然給客戶端返回的是200
狀態(tài)碼,所以我們還可能需要提取頁(yè)面的一些特征來(lái)判斷該代理IP是否可用嵌溢。比如知乎在判斷出IP有風(fēng)險(xiǎn)的時(shí)候同云,會(huì)彈出以下提示
我們可以查看頁(yè)面源碼,在title
中提取出安全驗(yàn)證
這個(gè)比較特殊的標(biāo)記堵腹,它可以作為判斷IP是否被屏蔽的標(biāo)準(zhǔn)炸站,如果怕誤判,我們還可以提取如verification
等關(guān)鍵詞來(lái)加強(qiáng)判斷邏輯疚顷。這種方式需要實(shí)測(cè)讓IP被屏蔽之后才能實(shí)現(xiàn)相關(guān)邏輯旱易。另一種方式是我們?cè)O(shè)置一個(gè)預(yù)期成功的標(biāo)記success_flag
,比如https://www.zhihu.com/question/47464143這個(gè)url,我們先通過(guò)正常情況下爬蟲(chóng)訪問(wèn)獲取到它的返回結(jié)果,然后找一個(gè)特殊的字符串作為成功返回的標(biāo)記腿堤,這里我選爬蟲(chóng)
這個(gè)字符串阀坏,我們?cè)僭O(shè)置ZhiHuValidator
的success_key=爬蟲(chóng)
即可。同時(shí)笆檀,你也可以強(qiáng)化該場(chǎng)景的校驗(yàn)方法忌堂,在ZhiHuValidator
中重寫(xiě)BaseValidator
的父方法is_ok(self, response)
,舉一個(gè)簡(jiǎn)單的例子def is_ok(self, response): return True if self.success_key in response.text and 'python' in response.text else False
4.將ZhiHuValidator
加入validators/init.py的all_validators
列表中
from .httpbin import (
HttpBinInitValidator, HttpValidator,
HttpsValidator)
from .zhihu import ZhiHuValidator
all_validators = [
HttpBinInitValidator, HttpValidator,
HttpsValidator, ZhiHuValidator
]
到這里酗洒,我們便完成zhihu
校驗(yàn)器的編寫(xiě)了士修。
配合該校驗(yàn)器抓取知乎的簡(jiǎn)要說(shuō)明如下
-
先啟動(dòng)代理抓取爬蟲(chóng)和定時(shí)任務(wù)調(diào)度器(這里我只啟動(dòng)了
common
這個(gè)代理抓取任務(wù))python crawler_booter.py --usage crawler common
python scheduler_booter.py --usage crawler common
-
再啟動(dòng)
zhihu
和init
校驗(yàn)器和定時(shí)任務(wù)調(diào)度器python crawler_booter.py --usage validator init zhihu
python scheduler_booter.py --usage validator zhihu
調(diào)用代理IP客戶端實(shí)現(xiàn)數(shù)據(jù)采集
如果代理IP使用過(guò)程有不清楚的請(qǐng)查看 haipproxy具體使用說(shuō)明