scrapy 忽略|屏蔽請求

背景:有時候在scrapy中,我們經常會碰到一些我們並不需要的url請求,一是它會帶來髒數據,而是它會佔用請求資源,造成不必要浪費.

解決辦法:碰到這種情況,我們可以自己寫一個過濾這些請求的中間件(middleware).

比如,我的這個是它會在url裏面有些關鍵字,當url中有這些關鍵字的時候,中間件就會把請求過濾掉.這是這個middleware的設計思路,下面來看具體怎麼去實現它:

# 需要用到的包
import re
from scrapy.exceptions import IgnoreRequest

# 中間件代碼
class UrlFilterMiddleware:
    """url filter middleware written by fcj"""
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        from urllib.parse import urlsplit  # 局部區域引用包
        black_set = {   # 關鍵字
            'beanie', 'brief', 'choker', 'hat', 'scraf', 'pajamas', 'slippes'
        }
        
        split_result = urlsplit(url=request.url).path  
        # 使用urlsplit切割url,並最後得到path,path一般都包含了關鍵字.
        split_set = set(re.split(r'[/_.-]', split_result))  
        # 再使用正則表達式,切割字符串,得到一個字符串列表,並set.
        intersection = split_set & black_set
        # set求和,若結果的set長度大於0,則兩個set間存在相同元素.這一步主要是避免迭代尋找共同元素.
        if len(intersection) > 0:
            raise IgnoreRequest('url filter')
            # 當有共同元素的時候,則證明url裏有關鍵字,拋出忽略請求的異常即可.
            # 官文對這個異常的描述:This exception can be raised by the Scheduler or 
            # any downloader middleware to indicate that the request should be ignored.
        else:
            return None
            # 當返回None值時,爬蟲會繼續對request做處理.

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章