基本上标题是什么。我在Windows 8.1上使用Python 2.7.9和Scrapy 0.24.5。
我介绍了TakeFirst输出处理器,以便在我的数据库中获取单个值,而不是单个项目列表对象。使用输出处理器时,管道接收的Item对象为None。如果我取出输出处理器,Item对象包含单个值列表并将它们正确写入我的数据库。
我完全不知道为什么会发生这种情况......以下是相关的代码摘录:
我的蜘蛛中的解析函数如下所示:
def parse(self, response):
chosen_selector = response.xpath("//article[contains(@class, 'someResults')]")
for props in chosen_selector:
loader = ItemLoader(MyItem(), selector=props)
loader.default_output_processor = TakeFirst() # <<< this causes a problem, unless commented out
loader.add_xpath('address_raw',
".//a[@class='someLocation']/text()")
loader.add_xpath(....)
....
yield loader.load_item()
将项目写入数据库的我的管道如下所示:
def process_item(self, item, spider):
session = self.Session()
raw_data = Raw_data(**item)
try:
session.add(raw_data)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return item
我在scrapy的ItemLoader类中设置了断点,以检查带有和不带输出处理器的Item。
在没有TakeFirst输出处理器的情况下发送到管道的项目;它是每个项目的单个值列表
{
'address_raw': [u'some location'],
'agent_source': ['example.com'],
'bathrooms': [u'4'],
'bedrooms': [u'4'],
'carparks': [u'4'],
'company': [u'some company'],
'datetime_parsed': [datetime.datetime(....)],
'extract_results': [u'<article ....>......</span></a></div></div></div></article>'],
....
'link_property': [u'some/link'],
'link_search': ['some/source'],
'page_number': ['9999'],
'price_high': 9999,
'price_raw': [u'$9999 per unit']
}
使用TakeFirst作为输出处理器发送到管道之前的项目,显示TakeFirst输出处理器似乎工作;一旦它到达上面的管道,这就是无。
{
'address_raw': u'some location',
'agent_source': 'example.com',
'bathrooms': u'4',
'bedrooms': u'4',
'carparks': u'4',
'company': u'some company',
'extract_results': u'<article ....>......</span></a></div></div></article>',
....
'link_property': u'some/link',
'link_search': 'some/source',
'page_number': '9999',
'price_raw': u'Offers Around $999'
}
数据模型
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, DateTime
import settings
DeclarativeBase = declarative_base()
....
class Raw_data(DeclarativeBase):
__tablename__ = "raw_data"
id = Column(Integer, primary_key=True)
address_raw = Column("address_raw", String)
... # all other columns, as per above, are also set to type string