中间件:
主要讨论的是下载中间件,明确一下顺序: download_middlewares --> server.url ---> spider_middleware
我主要是用来加header或者cookie,有的时候,用了scrapy-redis框架,直接往redis队列里塞网页,不同的domain有不同的cookie,不能共用一个cookie。
这里我不同的搜索引擎肯定用不同的cookie,整个process_request()函数返回None,表明加了这些cookie,header之后,继续运行,参考 编写下载中间件
代码:
import urlparse, urllib, random, re import scrapy from scrapy import signals class RandomUserAgent(object): def process_request(self, request, spider): # http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html#id2 有详细讲解 if request.method == 'GET': target_word = self.target(request) request.headers.setdefault('User-Agent', random.choice(USER_PC_AGENTS)) request.meta.setdefault('target_word', target_word) if 'baidu' in request.url: request.cookies = baiducookie elif 'so.360.cn' in request.url: request.cookies = san60cookie elif 'cn.bing' in request.url: request.cookies = biyingcookie pass def target(self, request): url = urllib.unquote(request.url) # 注意这里,网页的编码与解码 m = re.search(r'[wdq]=(.*?)$', url) # print m.group(1) target_word = m.group(1) if isinstance(target_word, unicode): try: target_word = target_word.encode('utf-8') except: pass return target_word
扩展
extension得和signal结合起来使用,爬虫在不停的干活的时候,往里面发送信号,发信号的意思是,他运行了信号的某个功能的时候,你在这个时候可以加函数进去,为所欲为。
例如:
class delay_test(object): def __init__(self, crawler): self.crawler = crawler crawler.signals.connect(self.bufore_request, signal=signals.response_received) @classmethod def from_crawler(cls, crawler): return cls(crawler) def bufore_request(self,response,spider): if 'www.so.com' in response.url: print '>>>sleep 2s' time.sleep(2) pass
同时在setting里面启用这个扩展
这段代码的意思是,每次获得一个url含有固定词的 response的时候,就会延迟2s,其实就是自定义设置里的delay了,我别的url不需要delay,特定的url需要delay,为所欲为。
编写这个很简单,主要是把信号的内容看懂就行了.
tips:
编写中间件和扩展可以参考源码进行改写,源码应该很容易看得懂,库里面的default_setting都有包含了哪些extensions和middlewares。然后再找到对应的代码,改写过后,只需要在项目里面setting里关闭默认的,启用你刚刚改写的即可。