Краулер создает дубликаты при двойном запуске?

Я использую фреймворк сканера «scrapy» в python, и я использую файл pipes.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 должен дважды записывать одни и те же данные в файл.


person station    schedule 15.03.2011    source источник
comment
Я думаю, решение состоит в том, чтобы предотвратить одновременный запуск нескольких экземпляров скрипта. Вы можете использовать для этого файловые блокировки (внутри вашего скрипта или снаружи, используя такие утилиты, как flock). Каковы причины наличия нескольких экземпляров сканера?   -  person Gregory    schedule 16.03.2011


Ответы (1)


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

person rmalouf    schedule 15.03.2011