DjangoとScrapyを接続して、DjangoからScrapyを動かすためのScrapy側の設定に関するメモです。
DjangoとScrapyの接続方法
以下のページを参考にしました。
前者の記事の情報は若干古いですが、これら2つの記事で共通して説明される内容がScrapyプロジェクトの設定ファイル(settings.py)で「DJANGO_SETTINGS_MODULE」を環境変数として設定し、django.setup()
関数を呼び出すことです。また、後者の記事で使われているscrapy-djangoitemライブラリでも同様の説明がされています。
このときDJANGO_SETTINGS_MODULEへ設定する値はDjangoのプロジェクトのsettings.pyファイルです。このDjangoのsettings.pyのPathを通すためにsys.path.append()
を使っています。
DjangoにもScrapyにもsettings.pyがあるためややこしいのですが、Scrapyのsettings.pyに設定を記述します。
Pathの設定に関する疑問
基本的に前者の記事に従い設定を試みたのですが、Pathの設定が間違っているのではないかと疑問に思いました。前者の記事では以下のように記載されています。
sys.path.append(os.path.dirname(os.path.abspath('.')))
このabspathの引数は相対Pathですので、どこをカレントディレクトリとしてPathを追加(append)したいのか疑問に思いました。後者の記事やscrapy-djangoitemライブラリではPathは絶対Pathでハードコーディングされています。
DJANGO_SETTINGS_MODULEへ設定する値がDjangoプロジェクトのsettings.pyであることからして、ここで追加したいPathはDjangoのプロジェクトがあるPath、つまりBASE_DIRになると思います。
そうするとos.path.abspath('.')
という記述はScrapyのsettings.pyがあるディレクトリを指すことになり、Pathが誤っているのではないかと考えました。
以下のteratailでもこのPathに関する質問がされています。
Scrapydの実行Pathに依る?
os.path.abspath('.')
のコードの説明のあとに、以下のようにscrapydの起動について説明されています。
That’s it. Now let’s start
https://alioguzhan.medium.com/how-to-use-scrapy-with-django-application-c16fabd0e62escrapyd
to make sure everything installed and configured properly. Insidescrapy_app/
folder run:
scrapy_appディレクトリは2つありますのでちょっと紛らわしいですが、説明の手順から考えるとおそらくDjangoのmanage.pyがあるディレクトリにあるScrapyのプロジェクトフォルダscrapy_appだと思います。
このディレクトリからPathを考えるとos.path.abspath('.')
はDjangoのBASE_DIRと一致します。
こちらの記事をもとに作られたDjangoとScrapyを接続したプロジェクトがありましたので、このReadmeを見てみるとScrapyプロジェクトフォルダのscrapy_appでScrapydを実行しているようです。
実際に動かしてみる
まずはScrapyのshellはではどのように動くか試してみました。ScrapydではなくScrapy本体です。
Pathの設定を以下のようにした状態で、わざとscrapy_app/scrapy_appでscrapy shell
のコマンドを実行すると、ModuleNotFoundErrorとなりました。
sys.path.append(os.path.dirname(os.path.abspath('.')))
そこで記事の通りscrapy_app/で同じようにscrapy shell
を実行してみると、こちらは正常に起動しました。Pathが正しいか否かの違いですので、当たり前といえば当たり前です。
そして肝心のScrapydの方ですが、scrapy_app/とscrapy_app/scrapy_app、さらにscrapy_app/の親ディレクトリの3通りでcurlコマンドによってスケジュールを実行してみましたが、どちらも正常実行できてしまいました。この3通りでやってみて2つはエラーになることを予想していましたが、動作としてはScrapyd経由でScrapyを実行するとsettings.pyのModuleNotFoundErrorとなりませんでした。
ここまでの動かし方としてはDjangoが絡んでいませんので、今のところはそれが影響しているのかな、と考えています。(現状はここまでの検証です。)
引き続きDjangoのViewからスケジュールを実行してみて動作を確認する予定です。
コメント