鍍金池/ 教程/ Python/ DjangoItem
Benchmarking
命令行工具(Command line tools)
下載器中間件(Downloader Middleware)
信號(hào)(Signals)
Telnet 終端(Telnet Console)
初窺 Scrapy
數(shù)據(jù)收集(Stats Collection)
Scrapyd
通用爬蟲(Broad Crawls)
Item Loaders
試驗(yàn)階段特性
Scrapy 入門教程
自動(dòng)限速(AutoThrottle)擴(kuò)展
Settings
Scrapy 終端(Scrapy shell)
下載項(xiàng)目圖片
DjangoItem
調(diào)試(Debugging)Spiders
選擇器(Selectors)
Feed exports
Spiders Contracts
借助 Firefox 來爬取
Logging
Spiders
Ubuntu 軟件包
實(shí)踐經(jīng)驗(yàn)(Common Practices)
安裝指南
Item Exporters
擴(kuò)展(Extensions)
Items
Spider 中間件(Middleware)
異常(Exceptions)
例子
發(fā)送 email
架構(gòu)概覽
常見問題(FAQ)
Jobs:暫停,恢復(fù)爬蟲
核心 API
使用 Firebug 進(jìn)行爬取
Item Pipeline
Link Extractors
Web Service
調(diào)試內(nèi)存溢出

DjangoItem

DjangoItem 是一個(gè) item 的類,其從 Django 模型中獲取字段(field)定義。 您可以簡(jiǎn)單地創(chuàng)建一個(gè) DjangoItem 并指定其關(guān)聯(lián)的 Django 模型。

除了獲得您 item 中定義的字段外, DjangoItem 提供了創(chuàng)建并獲得一個(gè)具有 item 數(shù)據(jù)的 Django 模型實(shí)例(Django model instance)的方法。

使用 DjangoItem

DjangoItem 使用方法與 Django 中的 ModelForms 類似。您創(chuàng)建一個(gè)子類,并定義其 django_model 屬性。這樣,您就可以得到一個(gè)字段與 Django 模型字段(model field)一一對(duì)應(yīng)的 item 了。

另外,您可以定義模型中沒有的字段,甚至是覆蓋模型中已經(jīng)定義的字段。

讓我們來看個(gè)例子:

創(chuàng)造一個(gè) Django 模型:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=255)
    age = models.IntegerField()

定義一個(gè)基本的 DjangoItem

from scrapy.contrib.djangoitem import DjangoItem

class PersonItem(DjangoItem):
    django_model = Person

DjangoItem 的使用方法和 Item 類似:

>>> p = PersonItem()
>>> p['name'] = 'John'
>>> p['age'] = '22'

要從 item 中獲取 Django 模型,調(diào)用 DjangoItem 中額外的方法 save()

>>> person = p.save()
>>> person.name
'John'
>>> person.age
'22'
>>> person.id
1

當(dāng)我們調(diào)用 save()時(shí),模型已經(jīng)保存了。我們可以在調(diào)用時(shí)帶上 commit=False 來避免保存, 并獲取到一個(gè)未保存的模型:

>>> person = p.save(commit=False)
>>> person.name
'John'
>>> person.age
'22'
>>> person.id
None

正如之前所說的,我們可以在 item 中加入字段:

import scrapy
from scrapy.contrib.djangoitem import DjangoItem

class PersonItem(DjangoItem):
    django_model = Person
    sex = scrapy.Field()
>>> p = PersonItem()
>>> p['name'] = 'John'
>>> p['age'] = '22'
>>> p['sex'] = 'M'

注解

當(dāng)執(zhí)行 save()時(shí)添加到 item 的字段不會(huì)有作用(taken into account)。

并且我們可以覆蓋模型中的字段:

class PersonItem(DjangoItem):
    django_model = Person
    name = scrapy.Field(default='No Name')

這在提供字段屬性時(shí)十分有用,例如您項(xiàng)目中使用的默認(rèn)或者其他屬性一樣。

DjangoItem 注意事項(xiàng)

DjangoItem 提供了在 Scrapy 項(xiàng)目中集成 DjangoItem 的簡(jiǎn)便方法,不過需要注意的是,如果在 Scrapy 中爬取大量(百萬級(jí))的 item 時(shí),Django ORM 擴(kuò)展得并不是很好(not scale well)。這是因?yàn)殛P(guān)系型后端對(duì)于一個(gè)密集型(intensive)應(yīng)用(例如 web 爬蟲)并不是一個(gè)很好的選擇,尤其是具有大量的索引的數(shù)據(jù)庫。

配置 Django 的設(shè)置

在 Django 應(yīng)用之外使用 Django 模型(model),您需要設(shè)置 DJANGO_SETTINGS_MODULE 環(huán)境變量以及 –大多數(shù)情況下– 修改 PYTHONPATH 環(huán)境變量來導(dǎo)入設(shè)置模塊。

完成這個(gè)配置有很多方法,具體選擇取決您的情況及偏好。 下面詳細(xì)給出了完成這個(gè)配置的最簡(jiǎn)單方法。

假設(shè)您項(xiàng)目的名稱為 mysite,位于/home/projects/mysite 且用 Person 模型創(chuàng)建了一個(gè)應(yīng)用 myapp。 這意味著您的目錄結(jié)構(gòu)類似于:

/home/projects/mysite
├── manage.py
├── myapp
│   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── mysite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

接著您需要將/home/projects/mysite 加入到 PYTHONPATH 環(huán)境變量中并將 mysite.settings 設(shè)置為 DJANGO_SETTINGS_MODULE 環(huán)境變量。 這可以在 Scrapy 設(shè)置文件中添加下列代碼:

import sys
sys.path.append('/home/projects/mysite')

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

注意,由于我們?cè)?python 運(yùn)行環(huán)境中,所以我們修改 sys.path 變量而不是 PYTHONPATH 環(huán)境變量。 如果所有設(shè)置正確,您應(yīng)該可以運(yùn)行 scrapy shell 命令并且導(dǎo)入 Person 模型(例如 from myapp.models import Person)。