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里关闭默认的,启用你刚刚改写的即可。

  • 相关阅读:
    mysql报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    MD5登陆密码的生成
    15. 3Sum、16. 3Sum Closest和18. 4Sum
    11. Container With Most Water
    8. String to Integer (atoi)
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    几种非线性激活函数介绍
    AI初探1
    AI初探
  • 原文地址:https://www.cnblogs.com/dahu-daqing/p/8109839.html
Copyright © 2011-2022 走看看