我目前有scrapy蜘蛛,它使用django模型抓取XML feed并将信息存储在postgres数据库中。
这一切都很完美,并获得我想要的确切信息。问题是数据库需要每天更新一次,包括新信息,更改信息或删除不再存在的信息。
所以基本上当蜘蛛运行时我希望它检查它是否已经在数据库中,如果它是完全相同的信息然后忽略它,如果信息已经改变了它或它不再存在,删除信息。
我似乎无法弄清楚如何做到这一点。任何想法都将不胜感激。
布赖恩
答案 0 :(得分:1)
How to update DjangoItem in Scrapy
可能重复NT3RP提供了一个很好的解决方案,可以在一个管道和一些功能中更新所有django模型。
你可以填充" false"从对象的数据构造的主键。然后你可以保存数据并在模型中更新 - 如果已经只在一个管道中被删除:
class ItemPersistencePipeline(object):
def process_item(self, item, spider):
try:
item_model = item_to_model(item)
except TypeError:
return item
model, created = get_or_create(item_model)
try:
update_model(model, item_model)
except Exception,e:
return e
return item
当然是方法:
def item_to_model(item):
model_class = getattr(item, 'django_model')
if not model_class:
raise TypeError("Item is not a `DjangoItem` or is misconfigured")
return item.instance
def get_or_create(model):
model_class = type(model)
created = False
try:
#We have no unique identifier at the moment
#use the model.primary for now
obj = model_class.objects.get(primary=model.primary)
except model_class.DoesNotExist:
created = True
obj = model # DjangoItem created a model for us.
return (obj, created)
from django.forms.models import model_to_dict
def update_model(destination, source, commit=True):
pk = destination.pk
source_dict = model_to_dict(source)
for (key, value) in source_dict.items():
setattr(destination, key, value)
setattr(destination, 'pk', pk)
if commit:
destination.save()
return destination
此外,你应该在django模型中定义字段"主要" 来搜索是否已经在新项目中删除了
<强> models.py 强>
class Parent(models.Model):
field1 = CharField()
#primary_key=True
primary = models.CharField(max_length=80)
class ParentX(models.Model):
field2 = CharField()
parent = models.OneToOneField(Parent, related_name = 'extra_properties')
primary = models.CharField(max_length=80)
class Child(models.Model):
field3 = CharField()
parent = models.ForeignKey(Parent, related_name='childs')
primary = models.CharField(max_length=80)