scrapy的中间件Download Middleware实现User-Agent随机切换
总架构理解Middleware
经过scrapy官网最新的架构图来理解:git
从图中咱们能够看出,在spiders和ENGINE说起ENGINE和DOWNLOADER之间均可以设置中间件,二者是双向的,而且是能够设置多层.github
如何实现随机更换User-Agent
这里要作的是经过本身在Downlaoder Middleware中定义一个类来实现随机更换User-Agent,可是咱们须要知道的是scrapy其实自己提供了一个user-agent这个咱们在源码中能够看到以下图:chrome
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-useragentdom
基本的使用例子:scrapy
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方法能够直接随机获取,上述代码的结果为:ide
关于配置和代码
这里我找了一个以前写好的爬虫,而后实现随机更换User-Agent,在settings配置文件以下:post
DOWNLOADER_MIDDLEWARES = { 'jobboleSpider.middlewares.RandomUserAgentMiddleware': 543, 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, } RANDOM_UA_TYPE= 'random'
这里咱们要将系统的UserAgent中间件设置为None,这样就不会启用,不然默认系统的这个中间会被启用
定义RANDOM_UA_TYPE这个是设置一个默认的值,若是这里不设置咱们会在代码中进行设置,在middleares.py中添加以下代码:spa
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-Agentcode