scrapy:Middleware / Pipeline单实例

时间:2018-01-02 19:00:31

标签: python scrapy

我正在创建一个本地响应缓存,我正在创建Pipeline,因为我需要根据从站点收集的ID来存储项目的信息。

现在我还需要创建Downloader Middleware,因为根据我之前存储的ID,我不想使用新的Request访问该网站,因此我拦截了{{} 1}}在发送到服务器之前,检查我的缓存中是否已存在该ID,如果是,则仅从我的缓存中返回相同的项目。

现在你看到RequestPipeline需要一起工作,所以分离看起来不是很干净(我也有两个变量,我想要独一无二),但是当我在各自的设置下设置:

Middleware

我得到两个不同的实例(检查构造函数上的日志消息,因此它被创建两次)。

如何确保只创建一个实例,并且我不会与项目的DOWNLOADER_MIDDLEWARES = { 'myproject.urlcache.CachePipelineMiddleware': 1, } ITEM_PIPELINES = { 'myproject.urlcache.CachePipelineMiddleware': 800, } Pipeline功能冲突?

1 个答案:

答案 0 :(得分:11)

我刚刚意识到这是一个简单的scrapy问题,Singleton实际上可以使用管道和中间件的相同实例。

我首先创建此class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] 类:

class CachePipelineMiddleware(object):

    __metaclass__ = Singleton

    def process_item(self, item, spider):
        # it works as a Pipeline

    def process_request(self, request, spider):
        # it works as a Middleware

然后,在管道/中间件的课程上,我添加了以下内容:

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

class Draw extends JFrame{

    public static int Framesize=1000;

    public static void main(String []args){
        Draw s=new Draw();
        s.setVisible(true);


    }

    public Draw(){
        JPanel panel=new JPanel();
        setSize(Framesize,Framesize);

        setVisible(true);
    }
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        for (int i=0;i<=1000;i+=50) {
            g2.draw(new Line2D.Float(i, 0, i, Framesize));
            g2.draw(new Line2D.Float(0, i, Framesize, i));

        }
        g2.setPaint(Color.RED);
        g2.draw(new Ellipse2D.Float(0,0,200,200));
        g2.drawString("Test", 100, 150);
    }

}