zoukankan      html  css  js  c++  java
  • 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里关闭默认的,启用你刚刚改写的即可。

  • 相关阅读:
    黑客长期摇号不中"黑"掉北京小客车摇号网
    网络犯罪新动向:“黑客”学历不高 年龄不超30岁
    McAfee重返科技业 研制D-Central防政府监视
    windows系统服务编程代码示例分享
    Fireeye火眼公司发布报告,评论中国网络间谍活动
    FBI是如何破获“美国少女”裸照勒索案的
    得到内网域管理员的5种常见方法
    别人在用你的什么技术在赚钱.其实你天天在做
    慢一点恋爱,别急着洞房
    元芳,关于向朋友借钱你怎么看
  • 原文地址:https://www.cnblogs.com/dahu-daqing/p/8109839.html
Copyright © 2011-2022 走看看