用于运行scrapy爬行的Django管理命令

时间:2017-09-21 10:26:35

标签: python django scrapy

他正在尝试创建一个django管理命令来运行我的scrapy脚本。 但是我在运行脚本时遇到了错误,

File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\Anaconda3\lib\site-packages\django\core\management\__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "C:\Users\Anaconda3\lib\site-packages\django\core\management\__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\myProject\scraper\management\commands\extract_data.py", line 13, in run_from_argv
    self.execute()
  File "C:\Users\Anaconda3\lib\site-packages\django\core\management\base.py", line 314, in execute
    if options['no_color']:
KeyError: 'no_color'

这是我的代码

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

3 个答案:

答案 0 :(得分:0)

如果你read the sourcerun_from_argv()负责(除了设置self._called_from_command_line标志和正确关闭数据库连接之后的其他重要事项)以创建参数解析器,有效地解析{{ 1}},使用默认值填充预期选项(“no_color”是其中之一)并使用已解析的参数和选项调用argv

这里你覆盖了self.execute()而没有调用父项的实现 - 所以没有完成上述任务 - 并且没有正确配置run_from_argv dict,直接调用self.execute()

最简单的解决方案显然只是保留对options的引用,然后调用父实现,即:

argv

答案 1 :(得分:0)

here所述。您需要在基本命令中添加以下内容。

def add_arguments(self, parser):
    parser.add_argument('args', nargs='*')

并将run_from_argv更改为以下内容:

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

因此,完整的基本命令文件将如下所示:

class Command(BaseCommand):

    # Need this from Django 1.8+ - https://stackoverflow.com/a/51761494/686255
    def add_arguments(self, parser):
        parser.add_argument('args', nargs='*')

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

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

答案 2 :(得分:0)

万一有人从Google偶然发现这个问题,我将尝试测试管理命令。为此,我发现使用call_command更容易。这是文档链接https://docs.djangoproject.com/en/2.1/topics/testing/tools/#topics-testing-management-commands

看起来像文档

from io import StringIO
from django.core.management import call_command
from django.test import TestCase

class ClosepollTest(TestCase):
    def test_command_output(self):
        out = StringIO()
        call_command('closepoll', stdout=out)
        self.assertIn('Expected output', out.getvalue())