文章由本人博客首发: http://qinfei.glrsmart.com/2018/11/07/scrapy-shi-zhan-4-cun-chu-dao-shu-ju-ku/
前面说了,顺顺利利地爬到了数据,我们可不是为了只是 print 出来炫技的,分析,自己建立关系,存库, 数据就易主了有木有?
我们这里使用 ORM 神器 sqlalchemy 听说过吗? 我在flask, twisted 里面经常用哦.
安装什么的都不说了,直接上代码,毕竟很多童鞋等着看代码,不想听我废话.
再说一句, 就一句. 在 ORM 里面 我就喜欢 models controllers 建一大堆,分层才好维护,虽然文件显得多了一些.什么? 这些文件建在哪一层目录? 别急, 我在最后一节(杂谈)附上我的工程目录结构.
先建 model:
init.py
from sqlalchemy.ext.declarative import declarative_base
# declarative_base()类工厂函数,会根据不同的数据库引擎创建基类, 通过继承基类来创建与数据库表对应的类
Base = declarative_base()
# 在这里 import models 中的对象如果mysql 表不存在会自动创建表
from .body_seg import BodySeg
from ..controllers import engine
Base.metadata.create_all(engine)
body_seg.py
# -*- coding: utf-8 -*-
from . import Base
from sqlalchemy import Column, String, Integer
# from sqlalchemy.orm import relationship
class BodySeg(Base):
__tablename__ = 'body_seg'
id = Column(Integer, nullable=False, primary_key=True, autoincrement=True)
seg_name = Column(String(32), nullable=True)
models 就完成啦.
下面 controllers:
init.py
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
SQLALCHEMY_DATABASE_URI = 'mysql+mysqldb://username:passwd@ip:port/dbname?charset=utf8'
engine = create_engine(SQLALCHEMY_DATABASE_URI, poolclass=NullPool)
Session = sessionmaker(bind=engine)
body_seg.py
from . import Session
from ..models.body_seg import BodySeg
from sqlalchemy.exc import IntegrityError
def add(seg_name):
'''
添加seg
:param seg_name:
:return:
'''
session = Session()
record = session.query(BodySeg).filter_by(seg_name=seg_name).first()
if not record:
record = BodySeg(seg_name=seg_name)
session.add(record)
try:
result = True
session.commit()
except IntegrityError:
session.rollback()
result = False
session.close()
return result
def get_all_segs():
'''
查询所有seg,只返回seg 名字
:return: seg名字列表,格式: [("name",), ("name",)]
'''
session = Session()
segs = session.query(BodySeg.seg_name).all()
session.close()
return segs
然后 controllers 也建好啦!
下面就是见证奇迹的时刻,我们再贴一遍 pipeline 里面的代码:
from .items import BodySegItem
from .controllers import body_seg
class BodySegPipeline:
def process_item(self, item, spider):
"""
处理大类数据
这个方法必须实现,每个item pipeline组件都需要调用该方法,
这个方法必须返回一个 Item 对象
被丢弃的item将不会被之后的pipeline组件所处理。
:param item: item (Item 对象) – 被爬取的item
:param spider: (Spider 对象) – 爬取该item的spider
:return:
"""
if isinstance(item, BodySegItem):
body_seg.add(seg_name=item["seg"])
return item
看到了吗? 直接使用 body_seg.add(seg_name=item["seg"])
就可以写入数据库啦, 也不用管数据库里面表有没有建好, sqlalchemy 会自动帮你处理的.
启动爬虫, 数据就会源源不断地流入到我们的数据库啦