2016-03-23 6 views
1

У меня есть scrapyd сервер с несколькими пауками, работающими одновременно, я запускаю пауков один за другим, используя конечную точку schedule.json. Все пауки записи содержимого на общий файл с помощью трубопроводаscrapyd несколько пауков, записывающих элементы в тот же файл

class JsonWriterPipeline(object): 

def __init__(self, json_filename): 
    # self.json_filepath = json_filepath 
    self.json_filename = json_filename 
    self.file = open(self.json_filename, 'wb') 

@classmethod 
def from_crawler(cls, crawler): 
    save_path='/tmp/' 
    json_filename=crawler.settings.get('json_filename', 'FM_raw_export.json') 
    completeName = os.path.join(save_path, json_filename) 
    return cls(
     completeName 
    ) 

def process_item(self, item, spider): 
    line = json.dumps(dict(item)) + "\n" 
    self.file.write(line) 
    return item 

После пауков работает, я могу видеть, как они собирают данные правильно, элементы хранятся в файлах XXXX.jl и пауки работает правильно, однако содержание сканирование не отражается на общем файле. Пауки, похоже, хорошо работают, однако трубопровод плохо справляется со своей работой и не собирает данные в общий файл.

Я также заметил, что только один паук пишет в одно и то же время в файле.

ответ

1

Я не вижу оснований для того, чтобы делать то, что вы делаете. Вы можете изменить настройку json_filename, установив аргументы на свой запрос scrapyd schedule.json. Затем вы можете заставить каждого паука генерировать несколько разные файлы, которые вы объединяете с последующей обработкой или во время запроса. Вы также можете написать файлы JSON, похожие на то, что у вас есть, только установив значение FEED_URI (example). Если вы одновременно пишете один файл из нескольких процессов (особенно когда вы открываете режим 'wb'), вы ищете поврежденные данные.

Edit:

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

Есть несколько решений, в том числе:

  • именованных каналов

Относительно легко реализовать и хорошо для очень маленьких предметов только (see here)

  • RabbitMQ или каким-либо другой очередями механизма

Отличное решение, но может быть немного переполненным

  • База данных, например. SQLite решение на основе

Хороший и простой, но, вероятно, требует кодирования (выборочная потребителя)

  • Хороший inotifywait основанное или другое решение для мониторинга файловой системы

Ницца и, вероятно, легко реализовать

Последний кажется мне самым привлекательным вариантом. Когда scrapy crawl заканчивает (spider_closed signal), переместите, скопируйте или создайте ссылку на файл FEED_URL в каталог, который вы контролируете с помощью сценария, такого как this. mv или ln - это атомная операция unix, поэтому вы должны быть в порядке. Возьмите скрипт, чтобы добавить новый файл в файл tmp, который вы подаете один раз в свою потребительскую программу.

Используя этот способ, вы используете экспортеры фида по умолчанию для записи ваших файлов. Конечное решение настолько просто, что вам не нужен конвейер. Простое расширение должно соответствовать счету.

На extensions.py в том же каталоге, settings.py:

from scrapy import signals 
from scrapy.exceptions import NotConfigured 

class MoveFileOnCloseExtension(object): 

    def __init__(self, feed_uri): 
     self.feed_uri = feed_uri 

    @classmethod 
    def from_crawler(cls, crawler): 
     # instantiate the extension object 
     feed_uri = crawler.settings.get('FEED_URI') 
     ext = cls(feed_uri) 

     crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) 

     # return the extension object 
     return ext 

    def spider_closed(self, spider): 
     # Move the file to the proper location 
     # os.rename(self.feed_uri, ... destination path...) 

На ваш settings.py:

EXTENSIONS = { 
    'myproject.extensions.MoveFileOnCloseExtension': 500, 
} 
+0

Спасибо за ваш ответ. Я думаю, что я плохо разбираюсь в том, как работают трубопроводы. По моему мнению, пауки генерируют элементы, элементы всех пауков передаются в конвейер, который является глобальным для всех из них и обрабатывает их. Из вашего ответа я предполагаю, что у каждого паука в некотором смысле есть собственный конвейер, и есть несколько конвейеров, работающих с одним и тем же файлом, и это вызывает проблемы. Я прав? , Я делаю это таким образом, потому что есть другой процесс, который делает некоторые вещи с содержимым и принимает только один файл. – silvestrelosada

+0

Фразы не на 100% точны, но то, что вы говорите, правильно. Более конкретно scrapyd проводит несколько процессов скрининга параллельно. Каждый процесс скрининга запускает паук и ваш конвейер. Это означает, что при выполнении этого обхода вы откроете тот же файл для записи из многих процессов, которые приведут к коррупции. «... только принимает один файл». Я уверен, что есть лучший способ сделать это. Можете ли вы запустить scrapyd, получить, например, 100 файлов из него, [concat их к одному] (http://stackoverflow.com/questions/4969641/append-one-file-to-another-in-linux), а затем передать это вашему процессу? Это более распространено. – neverlastn

+0

Знаете ли вы некоторую возможность поместить результат (предметы) всех пауков в один и тот же файл, используя только лоскутное? Спасибо – silvestrelosada

 Смежные вопросы

  • Нет связанных вопросов^_^