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

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

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

# -*- 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:])

Вместо того, чтобы звонить, например. 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, я получу только следующий ответ:

Usage: manage.py scrapy [options] 

manage.py: error: no such option: -o

Итак, мой вопрос: как расширить пользовательскую команду управления, чтобы принять параметры командной строки Scrapy?

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


person pemistahl    schedule 12.05.2012    source источник
comment
но разве мы не должны быть в верхнем каталоге для сканирования ?? Как это делается? @pemistahl   -  person Nabin    schedule 03.02.2014


Ответы (2)


Хорошо, я нашел решение своей проблемы. Это немного некрасиво, но это работает. Поскольку команда manage.py проекта Django не принимает параметры командной строки 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:])
person pemistahl    schedule 13.05.2012

Я думаю, вы действительно ищете рекомендацию 10 из Соглашения о синтаксисе аргументов POSIX:

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

Модуль Python optparse ведет себя таким образом даже под окнами.

Я поместил модуль настроек проекта 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

Проверено с помощью scrapy 0.12 и django 1.3.1

person Aryeh Leib Taurog    schedule 23.10.2012