Scrapy的pipelines使用sqlalchemy


前言

Scrapy爬取到的数据可以使用MySql持久化存储,通常Scrapy通过在pipiline.py里面连接数据库获取游标,然后写原生SQL语句来插入数据到Mysql里面,所以一旦数据字段较多时,pipiline里面会出现大段SQL语句,十分难受,那么有没办法跟Django一样,有一个模型然后直接model.save就可以存储数据呢?事实上SQLAlchemy就是Python里面最有名的ORM框架,使用它来写一个model类,然后就可以给Scrapy使用。

创建Model模块

由于我们项目下可能会有多个爬虫,因此我们建立一个Model包,然后在下面对应每个爬虫新增一个model的模块,我项目下已有四个爬虫,因此对应四个model模块:

1590823974399

由于是model包,因此必须有init.py文件,为了方便后面使用,我们将数据库连接方式和返回数据库连接会话的函数都放到init.py里面:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base


#创建对象基类
Base = declarative_base()

#初始化数据库连接
engine = create_engine('mysql+pymysql://root:12345678@localhost:3306/get_ais?charset=utf8',pool_size=100)

#返回数据库会话
def loadSession():
    Session = sessionmaker(bind=engine)
    session = Session()
    return session

在model包里面创建爬虫对应的model模块,其中的字段跟item里面的对应,例如get_ais_xs这个爬虫,对应的item类如下:


class GetAisItem_JQXS(scrapy.Item):
    # define the fields for your item here like:
    xs_name = scrapy.Field()
    xs_xq_url = scrapy.Field()
    xs_type = scrapy.Field()
    xs_pf = scrapy.Field()
    xs_createdate = scrapy.Field()
    xs_text = scrapy.Field()

根据以上item在model包里面创建ais_xs.py模块和存储表对应的类,内容如下:

from sqlalchemy import String,Column,DateTime,Text,Integer
from . import Base

#必须继承基类
class XS(Base):
    #类对应的数据库表名
    __tablename__ = 'ais_xs'
    #设置主建,不能重复
    xs_xq_url = Column(String(100),primary_key = True,nullable = False)
    xs_name = Column(String(100),nullable = True)
    xs_type = Column(String(20),nullable = True)
    xs_pf = Column(String(10),nullable = True)
    xs_createdate = Column(DateTime,nullable = True)
    xs_text = Column(Text,nullable = True)

在pipiline里面使用model类

上面已经创建了model,那么scrapy里面怎么使用呢?如下述代码,直接在pipiline里面引入即可,具体详见代码:

#引入model里面的基类、数据库连接、数据库连接会话函数
from .model import Base,engine,loadSession
#引入model里面对应爬虫的model模块
from .model import ais_xs
import logging

class GetAisPipeline:
    #搜索Base的所有子类,并在数据库中生成表
    Base.metadata.create_all(engine)

    def process_item(self, item, spider):
        try:
            #直接将爬虫yield的item赋值成一个model的对象
            a = ais_xs.XS(
                xs_xq_url = item['xs_xq_url'],
                xs_name = item['xs_name'][0],
                xs_type = item['xs_type'][0],
                xs_pf = item['xs_pf'][0],
                xs_createdate = item['xs_createdate'][0],
                xs_text = item['xs_text'][0]
            )
            #获取数据库连接
            session = loadSession()
            #将item变成的对象保存进数据库
            session.add(a)
            #提交事务
            session.commit()
        except Exception as e:
            logging.info(e)

如此及以达成了不使用SQL语句而持久化保存爬取到的数据到mysql的目标。


文章作者: 无咎
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无咎 !
评论
 上一篇
使用python将四万多图片分文件夹存储 使用python将四万多图片分文件夹存储
1 前言先说明下背景吧,之前学习Scrapy爬了一个网站的美女图片,爬完后发现数量居然有4W多个,此前完全没想到这么多,所以存储时直接放在了一个文件夹,导致现在打开文件夹时巨慢无比,因此想要批量给他们归个类,按不同的文件夹存储。 爬取图片时
下一篇 
Scrapy中使用USER_AGENT模拟浏览器请求 Scrapy中使用USER_AGENT模拟浏览器请求
前言在使用爬虫的过程中,经常遇到网站的一些反爬措施。通常Scrapy爬虫的请求头里面的用户代理user agent是固定的一种,很容易被识别出,因此许多网站将过滤指定user agent作为最基础的反爬手段,那么我们要绕开的方法就是每次请求
2020-05-30
  目录