11

Django 内からScrapy Web クロール フレームワークを実行できるようにしたいと考えています。Scrapy 自体は、scrapyそのコマンドを実行するためのコマンド ライン ツールのみを提供します。つまり、このツールは、外部プログラムから呼び出されるように意図的に作成されたわけではありません。

ユーザーMikhail Korobovは、Django カスタム管理コマンドから Scrapy を呼び出すという優れた解決策を思い付きました。便宜上、ここで彼の解決策を繰り返します。

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

eg を呼び出す代わりに、Django プロジェクト内からscrapy crawl domain.com実行できるようになりました。python manage.py scrapy crawl domain.comただし、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 モジュールのドキュメントも読みましたが、その後はよくわかりませんでした。この点で誰かが私を助けることができますか? よろしくお願いします!

4

2 に答える 2

5

さて、私は私の問題の解決策を見つけました。少し醜いですが、うまくいきます。Django プロジェクトのmanage.pyコマンドは Scrapy のコマンド ライン オプションを受け入れないため、オプション文字列を で受け入れられる 2 つの引数に分割しますmanage.py。解析が成功したら、2 つの引数を再び結合して 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:])
于 2012-05-13T12:47:27.657 に答える
3

POSIX引数構文規則ガイドライン10を本当に探していると思います:

引数 -- は、オプションの終わりを示す区切り文字として受け入れられる必要があります。後続の引数は、'-' 文字で始まっていても、オペランドとして扱われるべきです。-- 引数は、オプションまたはオペランドとして使用しないでください。

Python のoptparseモジュールは、ウィンドウの下でもこのように動作します。

引数リストにスクレイピー プロジェクト設定モジュールを配置したので、独立したアプリで個別のスクレイピー プロジェクトを作成できます。

# <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 でテスト済み

于 2012-10-23T21:19:48.670 に答える