在scrapy中使用django model來存儲數據

在scrapy中使用pipeline可以將抓取到的數據存儲於數據庫或者文件中,但在實際操作過程中,如果不採用第三方orm庫,需要自己構造sql語句,進行數據庫操作,如果操作數據庫的字段較多時,容易出現錯誤,並且爲重複的體力勞動。於是,考慮使用python比較成熟的第三方orm庫,將便於數據入庫的操作。由於筆者之前使用過django來搭建web站點,對django的model印象深刻,只需要將數據存儲於對象中,而該對象對應了數據庫中表,只需要調用簡單命令save等,就可以將數據入庫。因此,考慮使用django中的model來存儲數據。

目前,我還沒有找到將model模塊直接從django中剝離的辦法,只能採取比較笨重的方法(參考:http://doc.scrapy.org/en/0.24/topics/djangoitem.html),即新建一個django項目,然後用scrapy去調用其中已經設置好的model模塊,實現數據的存儲。若有更好的方法,希望告知。

首先就是安裝scrapy和django,由於涉及到很多第三方庫,此處可以參考官網文檔,此處的版本爲scrapy:0.24.5,django:1.7.7

安裝完畢後,分別新建django項目和scrapy項目,並且在django新項目下創建app silo分別命名如下,
$ scrapy startproject demo
$ django-admin.py startproject demosite
$ cd demosite/
$ python manage.py startapp silo
$ cd ../..
$ tree
.
└── django-scrapy
    ├── demo
    │   ├── demo
    │   │   ├── __init__.py
    │   │   ├── items.py
    │   │   ├── pipelines.py
    │   │   ├── settings.py
    │   │   └── spiders
    │   │       └── __init__.py
    │   └── scrapy.cfg
    └── demosite
        ├── demosite
        │   ├── __init__.py
        │   ├── __init__.pyc
        │   ├── settings.py
        │   ├── settings.pyc
        │   ├── urls.py
        │   └── wsgi.py
        ├── manage.py
        └── silo
            ├── admin.py
            ├── __init__.py
            ├── migrations
            │   └── __init__.py
            ├── models.py
            ├── tests.py
            └── views.py

首先,需要在django項目demosite的目錄下配置model,在創建好的silo app中添加與數據庫相互映射的類,

./django-scrapy/demosite/silo/models.py
from django.db import models

class Demo_data(models.Model):
    iAutoId         = models.AutoField(primary_key=True, default=None)
    title           = models.CharField(max_length=256, default=None)
...

然後在demotie的setting文件中配置數據庫以及app信息,

./django-scrapy/demosite/demosite
# 數據庫信息
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # 使用mysql進行數據存儲
        'NAME': 'demo_db',
        'USER': 'admin',
        'PASSWORD': 'admin',
        'HOST': '192168.0.100',
        'PORT': '3306'
    }
}

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'silo',     # 加入使用的app
)

然後返回demosite的根目錄 ./django-scrapy/demosite/,運行命令創建model以及數據庫映射
$ python manage.py makemigrations
$ python manage.py migrate
注:如果需要重新創建表,在數據中直接刪除表,會造成django項目的出錯,可以按照下面步驟操作(http://stackoverflow.com/questions/27583744/django-table-doesnt-exist)
1. 刪除數據庫中表
2. 在models.py中註釋對應的class
3. 在django項目根目錄下運行命令 
$ python manage.py makemigrations
$ python manage.py migrate --fake
4. 將models.py中的類取消註釋
5. 在django項目根目錄下運行命令
$ python manage.py makemigrations
$ python manage.py migrate
此時,可以看到,數據庫中將會創建一張全新的表

緊接着,需要在scrapy項目中進行配置,並且將django中創建的model導入其中。在./django-scrapy/demo/demo中的settings.py中進行下面配置

./django-scrapy/demo/demo/settings.py
import sys
sys.path.append('../../demosite')

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'demosite.settings'

然後在./django-scrapy/demo/demo/items.py中定義item,

./django-scrapy/demo/demo/items.py
from scrapy.contrib.djangoitem import DjangoItem
from silo.models import Demo_data

class DemoItem(DjangoItem):
    django_model =Demo_data

最後就可以在pipeline中進行數據的存儲,大功告成,比起之前繁瑣的sql語句,此處只需要一句save就解決問題。

./django-scrapy/demo/demo/pipelines.py
class DemoPipeline(object):
    def process_item(self, item, spider):
        item.save()
        return item

當然,該處還可以進行更深的挖掘,希望大家拍磚。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章