Crawler выдает дубликаты при запуске дважды? - PullRequest
1 голос
/ 15 марта 2011

Я использую каркас сканера "scrapy" в python и использую файл pipelines.py для хранения своих элементов в формате json в файле. Код для этого приведен ниже import json

class AYpiPipeline(object):
def __init__(self):
    self.file = open("a11ypi_dict.json","ab+")


# this method is called to process an item after it has been scraped.
def process_item(self, item, spider):
    d = {}    
    i = 0
# Here we are iterating over the scraped items and creating a dictionary of    dictionaries.
try:
    while i<len(item["foruri"]):
        d.setdefault(item["foruri"][i],{}).setdefault(item["rec"][i],{})[item["foruri_id"][i]] = item['thisurl'] + ":" + item["thisid"][i]
    i+=1
except IndexError:
    print "Index out of range"
    # Writing it to a file
    json.dump(d,self.file)
return item

Проблема в том, что, когда я запускаю свой сканер дважды (скажем), тогда в моем файле появляются дубликаты с ошибками. Я пытался предотвратить его, сначала прочитав файл, а затем сопоставив данные с новыми данными, которые нужно записать, но данные прочиталииз файла был формат json, поэтому я расшифровал его с помощью функции json.loads (), но он не работает:

import json 

class AYpiPipeline(object):
    def __init__(self):
        self.file = open("a11ypi_dict.json","ab+")
        self.temp = json.loads(file.read())

    # this method is called to process an item after it has been scraped.
    def process_item(self, item, spider):
        d = {}    
        i = 0
        # Here we are iterating over the scraped items and creating a dictionary of    dictionaries.
        try:
            while i<len(item["foruri"]):
            d.setdefault(item["foruri"][i],{}).setdefault(item["rec"][i],{})[item["foruri_id"][i]] = item['thisurl'] + ":" + item["thisid"][i]
            i+=1
        except IndexError:
            print "Index out of range"
        # Writing it to a file

             if d!=self.temp: #check whether the newly generated data doesn't match the one already in the file
                  json.dump(d,self.file)
        return item
    .

Пожалуйста, предложите способ сделать это.

Примечание. Обратите внимание, что мне нужно открыть файл в режиме «добавления», поскольку я могу сканировать другой набор ссылок, но при запуске сканера дважды с одним и тем же start_url необходимо дважды записать в файл одни и те же данные

1 Ответ

1 голос
/ 16 марта 2011

Вы можете отфильтровать дубликаты с помощью некоторого пользовательского промежуточного программного обеспечения, например, this . Однако для фактического использования этого в вашем пауке вам понадобятся еще две вещи: какой-то способ назначения идентификаторов элементам, чтобы фильтр мог идентифицировать дубликаты, и некоторый способ сохранения набора посещенных идентификаторов между запусками паука. Во-вторых, это просто - вы можете использовать что-нибудь питоническое, например, полку, или вы можете использовать один из многих популярных магазинов в наши дни. Однако первая часть будет сложнее и будет зависеть от проблемы, которую вы пытаетесь решить.

...