Пользовательская команда управления Django под управлением Scrapy: как включить опции Scrapy?

Я хочу быть в состоянии запуститьScrapy Web Framework изнутри Джанго. Сама Scrapy предоставляет только инструмент командной строкиscrapy для выполнения своих команд, то есть инструмент не был специально написан для вызова из внешней программы.

ПользовательМихаил Коробов придумалихорошее решениеа именно для вызова Scrapy из пользовательской команды управления Django. Для удобства повторю его решение здесь:

<code># -*- coding: utf-8 -*-
# myapp/management/commands/scrapy.py 

from __future__ import absolute_import
from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def run_from_argv(self, argv):
        self._argv = argv
        return super(Command, self).run_from_argv(argv)

    def handle(self, *args, **options):
        from scrapy.cmdline import execute
        execute(self._argv[1:])
</code>

Вместо того, чтобы звонить, например,scrapy crawl domain.com Теперь я могу сделатьpython manage.py scrapy crawl domain.com из проекта Django. Однако параметры команды Scrapy вообще не анализируются. Если я сделаюpython manage.py scrapy crawl domain.com -o scraped_data.json -t jsonЯ только получаю следующий ответ:

<code>Usage: manage.py scrapy [options] 

manage.py: error: no such option: -o
</code>

So my question is, how to extend the custom management command to adopt Scrapy's command line options?

К сожалению, Djangoдокументация этой части не очень обширный. Я также прочитал документацию Pythonмодуль optparse но потом мне стало не понятнее. Может ли кто-нибудь помочь мне в этом отношении? Заранее большое спасибо!

 Nabin03 февр. 2014 г., 09:45
но разве мы не должны быть в верхнем каталоге для сканирования ?? Как это сделать? @ Pemistahl

Ответы на вопрос(2)

Решение Вопроса

я нашел решение своей проблемы. Это немного некрасиво, но это работает. Поскольку проект Djangomanage.pyоманда @ не принимает параметры командной строки Scrapy, я разбил строку параметров на два аргумента, которые принимаютсяmanage.py. После успешного разбора я воссоединяюсь с двумя аргументами и передаю их в Scrapy.

То есть вместо того, чтобы писать

python manage.py scrapy crawl domain.com -o scraped_data.json -t json

Я ставлю пробелы между этими параметрами

python manage.py scrapy crawl domain.com - o scraped_data.json - t json

Моя функция управления выглядит так:

def handle(self, *args, **options):
    arguments = self._argv[1:]
    for arg in arguments:
        if arg in ('-', '--'):
            i = arguments.index(arg)
            new_arg = ''.join((arguments[i], arguments[i+1]))
            del arguments[i:i+2]
            arguments.insert(i, new_arg)

    from scrapy.cmdline import execute
    execute(arguments)

Между тем Михаил Коробов предоставил оптимальное решение. Глянь сюда

# -*- coding: utf-8 -*- 
# myapp/management/commands/scrapy.py 

from __future__ import absolute_import
from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def run_from_argv(self, argv):
        self._argv = argv
        self.execute()

    def handle(self, *args, **options):
        from scrapy.cmdline import execute
        execute(self._argv[1:])

Руководство 10 изоглашения о синтаксисе аргументов @POSIX:

Аргумент - должен быть принят в качестве разделителя, указывающего конец опций. Любые последующие аргументы должны рассматриваться как операнды, даже если они начинаются с символа «-». Аргумент - не должен использоваться как опция или как операнд.

Python'soptparseодуль @ ведет себя таким образом, даже под Windows.

Я поместил модуль настроек проекта scrapy в список аргументов, чтобы я мог создавать отдельные проекты scrapy в независимых приложениях:

# <app>/management/commands/scrapy.py
from __future__ import absolute_import
import os

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def handle(self, *args, **options):
        os.environ['SCRAPY_SETTINGS_MODULE'] = args[0]
        from scrapy.cmdline import execute
        # scrapy ignores args[0], requires a mutable seq
        execute(list(args))

Вызывается следующим образом:

python manage.py scrapy myapp.scrapyproj.settings crawl domain.com -- -o scraped_data.json -t json

Испытано с помощью скрапа 0.12 и django 1.3.1

Ваш ответ на вопрос