主な誤解は、パッケージ パスと設定モジュール パスだと思います。外部スクリプトから django のモデルを使用するには、DJANGO_SETTINGS_MODULE
. 次に、このモジュールをインポート可能にする必要があります (つまり、設定パスがmyproject.settings
の場合、ステートメントfrom myproject import settings
は Python シェルで機能する必要があります)。
django のほとんどのプロジェクトはデフォルト以外のパスで作成されるため、プロジェクトのパスを環境変数PYTHONPATH
に追加する必要があります。PYTHONPATH
以下は、完全に機能する (そして最小限の) Django モデルを Scrapy プロジェクトに統合するための段階的なガイドです。
注:この手順は、最終編集日時点で機能します。うまくいかない場合は、コメントを追加して、問題と Scrapy/Django のバージョンを説明してください。
プロジェクトは/home/rolando/projects
ディレクトリ内に作成されます。
django プロジェクトを開始します。
$ cd ~/projects
$ django-admin startproject myweb
$ cd myweb
$ ./manage.py startapp myapp
でモデルを作成しますmyapp/models.py
。
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=32)
に追加myapp
します。INSTALLED_APPS
myweb/settings.py
# at the end of settings.py
INSTALLED_APPS += ('myapp',)
でデータベース設定を設定しmyweb/settings.py
ます。
# at the end of settings.py
DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3'
DATABASES['default']['NAME'] = '/tmp/myweb.db'
データベースを作成します。
$ ./manage.py syncdb --noinput
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
スクレイピー プロジェクトを作成します。
$ cd ~/projects
$ scrapy startproject mybot
$ cd mybot
でアイテムを作成しますmybot/items.py
。
注: Scrapy の新しいバージョンでは、 をインストールscrapy_djangoitem
して使用する必要がありますfrom scrapy_djangoitem import DjangoItem
。
from scrapy.contrib.djangoitem import DjangoItem
from scrapy.item import Field
from myapp.models import Person
class PersonItem(DjangoItem):
# fields for this item are automatically created from the django model
django_model = Person
最終的なディレクトリ構造は次のとおりです。
/home/rolando/projects
├── mybot
│ ├── mybot
│ │ ├── __init__.py
│ │ ├── items.py
│ │ ├── pipelines.py
│ │ ├── settings.py
│ │ └── spiders
│ │ └── __init__.py
│ └── scrapy.cfg
└── myweb
├── manage.py
├── myapp
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── myweb
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
ここから、基本的に、scrapy プロジェクトで django モデルを使用するために必要なコードは完了です。コマンドを使用してすぐにテストできますscrapy shell
が、必要な環境変数に注意してください。
$ cd ~/projects/mybot
$ PYTHONPATH=~/projects/myweb DJANGO_SETTINGS_MODULE=myweb.settings scrapy shell
# ... scrapy banner, debug messages, python banner, etc.
In [1]: from mybot.items import PersonItem
In [2]: i = PersonItem(name='rolando')
In [3]: i.save()
Out[3]: <Person: Person object>
In [4]: PersonItem.django_model.objects.get(name='rolando')
Out[4]: <Person: Person object>
したがって、意図したとおりに機能しています。
最後に、ボットを実行するたびに環境変数を設定する必要はありません。この問題に対処するための多くの代替手段がありますが、プロジェクトのパッケージが実際に で設定されたパスにインストールされるのが最善の方法ですPYTHONPATH
。
これは最も簡単な解決策の 1 つです。この行をmybot/settings.py
ファイルに追加して、環境変数を設定します。
# Setting up django's project full path.
import sys
sys.path.insert(0, '/home/rolando/projects/myweb')
# Setting up django's settings module name.
# This module is located at /home/rolando/projects/myweb/myweb/settings.py.
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'myweb.settings'
# Since Django 1.7, setup() call is required to populate the apps registry.
import django; django.setup()
注:パス ハッキングへのより良いアプローチは、両方のプロジェクトにsetuptools
ベースsetup.py
のファイルを配置して実行することです。python setup.py develop
これにより、プロジェクト パスが python のパスにリンクされます (使用すると想定していますvirtualenv
)。
それは十分です。完全を期すために、完全に機能するプロジェクトの基本的なスパイダーとパイプラインを次に示します。
スパイダーを作成します。
$ cd ~/projects/mybot
$ scrapy genspider -t basic example example.com
スパイダーコード:
# file: mybot/spiders/example.py
from scrapy.spider import BaseSpider
from mybot.items import PersonItem
class ExampleSpider(BaseSpider):
name = "example"
allowed_domains = ["example.com"]
start_urls = ['http://www.example.com/']
def parse(self, response):
# do stuff
return PersonItem(name='rolando')
mybot/pipelines.py
アイテムを保存するためのパイプラインを作成します。
class MybotPipeline(object):
def process_item(self, item, spider):
item.save()
return item
ここではitem.save()
、クラスを使用している場合に使用するかDjangoItem
、django モデルを直接インポートしてオブジェクトを手動で作成できます。どちらの方法でも、主な問題は環境変数を定義して、django モデルを使用できるようにすることです。
パイプライン設定をmybot/settings.py
ファイルに追加します。
ITEM_PIPELINES = {
'mybot.pipelines.MybotPipeline': 1000,
}
スパイダーを実行します。
$ scrapy crawl example