Ответ 1
Я думаю, что основное заблуждение - путь пакета к пути модуля настроек. Чтобы использовать модели django из внешнего script, вам нужно установить 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',)
-
Задайте настройки моего db в
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)
-
Создайте проект scrapy.
$ 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
Отсюда, в основном, мы делаем код, необходимый для использования моделей django в проекте scrapy. Мы можем проверить его сразу с помощью команды 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
.
Это одно из самых простых решений: добавьте эти строки в ваш файл mybot/settings.py
, чтобы настроить переменные среды.
# Setting up django project full path.
import sys
sys.path.insert(0, '/home/rolando/projects/myweb')
# Setting up django 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