Я не вижу веских причин делать то, что вы делаете :) Вы можете изменить настройку json_filename
, задав аргументы в своем запросе schedule.json
в scrapyd. Затем вы можете заставить каждого паука генерировать немного разные файлы, которые вы объединяете при постобработке или во время запроса. Вы также можете писать файлы JSON, аналогичные вашим, просто установив значение FEED_URI
(пример). Если вы записываете в один файл одновременно из нескольких процессов (особенно при открытии в режиме 'wb'
), вы ищете поврежденные данные.
Редактировать:
Немного лучше поняв, что вам нужно — в данном случае — scrapyd запускает несколько обходов, запуская разных пауков, каждый из которых сканирует разные веб-сайты. Процесс-потребитель постоянно отслеживает один файл.
Есть несколько решений, в том числе:
Относительно прост в реализации и подходит только для очень маленьких элементов (см. здесь)
- RabbitMQ или какой-либо другой механизм очередей
Отличное решение, но может быть немного излишним
- База данных, например. Решение на основе SQLite
Красивый и простой, но, вероятно, требует некоторого кодирования (пользовательский потребитель)
- Хорошее решение для мониторинга файловой системы на основе
inotifywait
или другого
Красиво и, вероятно, легко реализовать
Последний вариант мне кажется наиболее привлекательным. Когда scrapy crawl
завершится (spider_closed signal), переместитесь, скопируйте или создайте программную ссылку для файла FEED_URL
в каталог, который вы отслеживаете с помощью сценария, например это. 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,
}
person
neverlastn
schedule
24.03.2016