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

 

posted @   dahu1  Views(1331)  Comments(0Edit  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示