2017-07-22 2 views
0

Je veux éviter d'ajouter des données en double et juste 1) mettre à jour un champ (nombre de vues) ou 2) tous les champs qui avaient changé dans le site Web. Pour ce faire, j'utilise un identifiant (origin_id) que j'ai trouvé sur le site que je suis en train de gratter.Comment éviter d'ajouter des données en double dans Scrapy en utilisant MongoDB?

Pipelines

class MongoDBPipeline(object): 

def __init__(self): 
    connection = pymongo.MongoClient(
     settings['MONGODB_SERVER'], 
     settings['MONGODB_PORT'] 
    ) 
    db = connection[settings['MONGODB_DB']] 
    self.collection = db[settings['MONGODB_COLLECTION']] 

def process_item(self, item, spider): 
    valid = True 
    for data in item: 
     if not data: 
      valid = False 
      raise DropItem("Missing {0}!".format(data)) 
    if valid: 
     # Update item if it is in the database and insert otherwise. 
     self.collection.update({'origin_id': item['origin_id']}, dict(item), upsert=True) 
    return item 

MongoDB enregistrement

{ 
    "_id" : ObjectId("59725e919a1a6b7f0350027a"), 
    "origin_id" : "12256699", 
    "views":"556", 
    "url":"...", 
    "title":"...", 
} 

S'il vous plaît laissez-moi savoir si vous voulez plus de détails ...

+0

Alors, quel est le problème? Ce sont des "upserts". Par nature, il met à jour les données existantes en fonction des informations contenues dans la requête ou "crée" lorsque cette requête n'aboutit à rien. Donc, ce n'est vraiment pas clair quel est votre problème. Si un problème du tout. –

+0

Par exemple le nombre de vues où il n'est pas mis à jour –

+0

Tout ce que vous faites est d'envoyer le résultat de 'dict (item)' et d'écraser tout ce qui a été trouvé. Qu'attendez-vous? Qu'est-ce que cela a à voir avec les doublons? Si vous venez ici pour poser des questions, vous devez être «très spécifique» et montrer un résultat attendu et permettre aux gens de se reproduire. Voir [Comment créer un exemple minimal, complet et vérifiable] (https://stackoverflow.com/help/mcve) –

Répondre

0

Vous devez incrémenter views champ par 1 si le origin_id existe dans le document.

Notez que vous ne pouvez définir les autres champs comme ils détiennent des valeurs non numériques.

Ceci est également nécessaire afin d'ignorer une requête supplémentaire qui vérifie si un document avec ce origin_id existe dans la collection.

self.collection.update({ 
    'origin_id': item['origin_id']}, 
    { 
     '$set': {'url': item['url'], 'title': item['title']}, 
     '$inc': {'views': 1} 
    } 
}, 
upsert=True) 
+0

Merci beaucoup ... mais j'obtiens le nombre de vues directement du site que je gratte. Exemple: supposons que le nombre de vues était de 555 dans le document (la première fois que le contenu a été gratté), puis quand j'ai gratté le même contenu, le nombre de vues est passé à 799! Alors, comment puis-je écraser le nombre de vues passées dans le document? S'il vous plaît aider –

+0

Si je vous comprends bien, vous voulez remplacer les données pour un identifiant qui existe déjà. Je ne pense pas que vous ayez besoin d'augmenter les vues pour cela. Vous pouvez écrire cela dans l'ensemble. Qu'en est-il de ''$ set': {'url': item ['url'], 'title': item ['title'], 'views': item ['views']}'? Vous devez également supprimer la requête d'incrémentation –

+0

C'est ce que je veux mais je ne mets pas encore le nombre de vues à jour! BTW Je ne veux pas écraser l'ensemble des données depuis le nombre de vues qui est mis à jour à partir du site que je gratte ... –