我正在创建一个本地响应缓存,我正在创建Pipeline
,因为我需要根据从站点收集的ID来存储项目的信息。
现在我还需要创建Downloader Middleware
,因为根据我之前存储的ID,我不想使用新的Request
访问该网站,因此我拦截了{{} 1}}在发送到服务器之前,检查我的缓存中是否已存在该ID,如果是,则仅从我的缓存中返回相同的项目。
现在你看到Request
和Pipeline
需要一起工作,所以分离看起来不是很干净(我也有两个变量,我想要独一无二),但是当我在各自的设置下设置:
Middleware
我得到两个不同的实例(检查构造函数上的日志消息,因此它被创建两次)。
如何确保只创建一个实例,并且我不会与项目的DOWNLOADER_MIDDLEWARES = {
'myproject.urlcache.CachePipelineMiddleware': 1,
}
ITEM_PIPELINES = {
'myproject.urlcache.CachePipelineMiddleware': 800,
}
和Pipeline
功能冲突?
答案 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);
}
}