1. 程式人生 > >scrapy的中介軟體Downloader Middleware實現User-Agent隨機切換

scrapy的中介軟體Downloader Middleware實現User-Agent隨機切換

scrapy的中介軟體Download Middleware實現User-Agent隨機切換

 

總架構理解Middleware

通過scrapy官網最新的架構圖來理解:

從圖中我們可以看出,在spiders和ENGINE提及ENGINE和DOWNLOADER之間都可以設定中介軟體,兩者是雙向的,並且是可以設定多層.

 

如何實現隨機更換User-Agent

這裡要做的是通過自己在Downlaoder Middleware中定義一個類來實現隨機更換User-Agent,但是我們需要知道的是scrapy其實本身提供了一個user-agent這個我們在原始碼中可以看到如下圖:

from scrapy import signals
class UserAgentMiddleware(object):
    """This middleware allows spiders to override the user_agent"""

    def __init__(self, user_agent='Scrapy'):
        self.user_agent = user_agent

    @classmethod
    def from_crawler(cls, crawler):
        o 
= cls(crawler.settings['USER_AGENT']) crawler.signals.connect(o.spider_opened, signal=signals.spider_opened) return o def spider_opened(self, spider): self.user_agent = getattr(spider, 'user_agent', self.user_agent) def process_request(self, request, spider):
if self.user_agent: request.headers.setdefault(b'User-Agent', self.user_agent)

從原始碼中可以知道,預設scrapy的user_agent=‘Scrapy’,並且這裡在這個類裡有一個類方法from_crawler會從settings裡獲取USER_AGENT這個配置,如果settings配置檔案中沒有配置,則會採用預設的Scrapy,process_request方法會在請求頭中設定User-Agent.

關於隨機切換User-Agent的庫

github地址為:https://github.com/hellysmile/fake-useragent
安裝:pip install fake-useragent

基本的使用例子:

from fake_useragent import UserAgent

ua = UserAgent()

print(ua.ie)
print(ua.chrome)
print(ua.Firefox)
print(ua.random)
print(ua.random)
print(ua.random)

這裡可以獲取我們想要的常用的User-Agent,並且這裡提供了一個random方法可以直接隨機獲取,上述程式碼的結果為:

關於配置和程式碼

這裡我找了一個之前寫好的爬蟲,然後實現隨機更換User-Agent,在settings配置檔案如下:

DOWNLOADER_MIDDLEWARES = {
    'jobboleSpider.middlewares.RandomUserAgentMiddleware': 543,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}

RANDOM_UA_TYPE= 'random'

這裡我們要將系統的UserAgent中介軟體設定為None,這樣就不會啟用,否則預設系統的這個中間會被啟用
定義RANDOM_UA_TYPE這個是設定一個預設的值,如果這裡不設定我們會在程式碼中進行設定,在middleares.py中新增如下程式碼:

class RandomUserAgentMiddleware(object):
    '''
    隨機更換User-Agent
    '''
    def __init__(self,crawler):
        super(RandomUserAgentMiddleware, self).__init__()
        self.ua = UserAgent()
        self.ua_type = crawler.settings.get('RANDOM_UA_TYPE','random')

    @classmethod
    def from_crawler(cls,crawler):
        return cls(crawler)

    def process_request(self,request,spider):

        def get_ua():
            return getattr(self.ua,self.ua_type)
        request.headers.setdefault('User-Agent',get_ua())

上述程式碼的一個簡單分析描述:
1. 通過crawler.settings.get來獲取配置檔案中的配置,如果沒有配置則預設是random,如果配置了ie或者chrome等就會獲取到相應的配置
2. 在process_request方法中我們嵌套了一個get_ua方法,get_ua其實就是為了執行ua.ua_type,但是這裡無法使用self.ua.self.us_type,所以利用了getattr方法來直接獲取,最後通過request.heasers.setdefault來設定User-Agent

 

總架構理解Middleware

通過scrapy官網最新的架構圖來理解:

從圖中我們可以看出,在spiders和ENGINE提及ENGINE和DOWNLOADER之間都可以設定中介軟體,兩者是雙向的,並且是可以設定多層.

 

如何實現隨機更換User-Agent

這裡要做的是通過自己在Downlaoder Middleware中定義一個類來實現隨機更換User-Agent,但是我們需要知道的是scrapy其實本身提供了一個user-agent這個我們在原始碼中可以看到如下圖:

from scrapy import signals
class UserAgentMiddleware(object):
    """This middleware allows spiders to override the user_agent"""

    def __init__(self, user_agent='Scrapy'):
        self.user_agent = user_agent

    @classmethod
    def from_crawler(cls, crawler):
        o = cls(crawler.settings['USER_AGENT'])
        crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
        return o

    def spider_opened(self, spider):
        self.user_agent = getattr(spider, 'user_agent', self.user_agent)

    def process_request(self, request, spider):
        if self.user_agent:
            request.headers.setdefault(b'User-Agent', self.user_agent)

從原始碼中可以知道,預設scrapy的user_agent=‘Scrapy’,並且這裡在這個類裡有一個類方法from_crawler會從settings裡獲取USER_AGENT這個配置,如果settings配置檔案中沒有配置,則會採用預設的Scrapy,process_request方法會在請求頭中設定User-Agent.

關於隨機切換User-Agent的庫

github地址為:https://github.com/hellysmile/fake-useragent
安裝:pip install fake-useragent

基本的使用例子:

from fake_useragent import UserAgent

ua = UserAgent()

print(ua.ie)
print(ua.chrome)
print(ua.Firefox)
print(ua.random)
print(ua.random)
print(ua.random)

這裡可以獲取我們想要的常用的User-Agent,並且這裡提供了一個random方法可以直接隨機獲取,上述程式碼的結果為:

關於配置和程式碼

這裡我找了一個之前寫好的爬蟲,然後實現隨機更換User-Agent,在settings配置檔案如下:

DOWNLOADER_MIDDLEWARES = {
    'jobboleSpider.middlewares.RandomUserAgentMiddleware': 543,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}

RANDOM_UA_TYPE= 'random'

這裡我們要將系統的UserAgent中介軟體設定為None,這樣就不會啟用,否則預設系統的這個中間會被啟用
定義RANDOM_UA_TYPE這個是設定一個預設的值,如果這裡不設定我們會在程式碼中進行設定,在middleares.py中新增如下程式碼:

class RandomUserAgentMiddleware(object):
    '''
    隨機更換User-Agent
    '''
    def __init__(self,crawler):
        super(RandomUserAgentMiddleware, self).__init__()
        self.ua = UserAgent()
        self.ua_type = crawler.settings.get('RANDOM_UA_TYPE','random')

    @classmethod
    def from_crawler(cls,crawler):
        return cls(crawler)

    def process_request(self,request,spider):

        def get_ua():
            return getattr(self.ua,self.ua_type)
        request.headers.setdefault('User-Agent',get_ua())

上述程式碼的一個簡單分析描述:
1. 通過crawler.settings.get來獲取配置檔案中的配置,如果沒有配置則預設是random,如果配置了ie或者chrome等就會獲取到相應的配置
2. 在process_request方法中我們嵌套了一個get_ua方法,get_ua其實就是為了執行ua.ua_type,但是這裡無法使用self.ua.self.us_type,所以利用了getattr方法來直接獲取,最後通過request.heasers.setdefault來設定User-Agent