總架構理解Middleware
通過scrapy官網最新的架構圖來理解:
這個圖較之前的圖順序更加清晰,從圖中我們可以看出,在spiders和ENGINE提及ENGINE和DOWNLOADER之間都可以設置中間件,兩者是雙向的,並且是可以設置多層.
關於Downloader Middleware我在http://www.cnblogs.com/zhaof/p/7198407.html 這篇博客中已經寫了詳細的使用介紹。
如何實現隨機更換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
通過上面的配置我們就實現了每次請求隨機更換User-Agent