scrapy进阶-编写中间件和扩展

中间件:

主要讨论的是下载中间件,明确一下顺序: 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里关闭默认的,启用你刚刚改写的即可。

原文地址:https://www.cnblogs.com/dahu-daqing/p/8109839.html