Scrapy框架系列--数据不保存,就是耍流氓(3)

目录

  • 前言

  • Items

  • Pipelines

  • 瞎比比

前言

OK,通过签名两篇文章《爬虫利器初体验(1)》《听说你的爬虫又被封了?(2)》,我们初体验也过了,爬虫代码健壮性也升级为 PLUS 了。都分析到这个地步了,是不是感觉还少了点什么?对,我们还没保存数据呀?不保存,这不是瞎忙活吗?

Items

item 是我们保存数据的容器,其类似于 python 中的字典。使用 item 的好处在于: Item 提供了额外保护机制来避免拼写错误导致的未定义字段错误。且看栗子:

import scrapyclass Doubantop250Item(scrapy.Item):    title = scrapy.Field()  # 电影名字    star = scrapy.Field()  # 电影评分    quote = scrapy.Field()  # 脍炙人口的一句话    movieInfo = scrapy.Field()  # 电影的描述信息,包括导演、主演、电影类型

Pipelines

pipelines.py 一般我们用于保存数据,其方法的一些介绍如下图。下面,我会分多种方式来保存我们的数据,避免你耍流氓。

640?



640?

保存到 Json

import jsonclass JsonPipeline(object):    file_name = base_dir + '/doubanTop250/data.json'  # json 文件路径    def process_item(self, item, spider):        file = open(self.file_name, 'r', encoding='utf-8')        load_data = json.load(file)        load_data.append({"title": item["title"].strip()}) # 追加数据        file = open(self.file_name, 'w', encoding='utf-8')        json.dump(load_data, file, ensure_ascii=False) # 保存数据        file.close()        return item


640?

保存到 CSV

    def appendDta2Csv(self, file_name, new_headers, new_data):        with open(file_name,'r') as f:            f_csv = csv.reader(f)            try:# 如何有源文件没有 headers ,将调用传进来的 headers                headers = next(f_csv)            except:                headers = new_headers            old_data = list(f_csv)            old_data.append(new_data) # 追加新的数据            with open(file_name, 'w') as f2:# 保存数据                f_csv = csv.writer(f2)                f_csv.writerow(headers)                f_csv.writerows(old_data)                f2.close()            f.close()    def process_item(self, item, spider):        self.appendDta2Csv(self.file_name, ["title"], [item["title"].strip()])        return item


640?

保存到 MongoDB

from pymongo import MongoClientimport osbase_dir = os.getcwd()class MongoPipeline(object):    # 实现保存到mongo数据库的类,    collection = 'douban'  # mongo 数据库的 collection 名字    def __init__(self, mongo_uri, db_name, db_user, db_pass):        self.mongo_uri = mongo_uri        self.db_name = db_name        self.db_user = db_user        self.db_pass = db_pass    @classmethod    def from_crawler(cls, crawler):        # scrapy 为我们访问settings提供了这样的一个方法,这里,        # 我们需要从 settings.py 文件中,取得数据库的URI和数据库名称        return cls(            mongo_uri=crawler.settings.get('MONGO_URI'),            db_name=crawler.settings.get('DB_NAME'),            db_user=crawler.settings.get('DB_USER'),            db_pass=crawler.settings.get('DB_PASS'))    def open_spider(self, spider):  # 爬虫启动时调用,连接到数据库        self.client = MongoClient(self.mongo_uri)        self.zfdb = self.client[self.db_name]        self.zfdb.authenticate(self.db_user, self.db_pass)    def close_spider(self, spider):  # 爬虫关闭时调用,关闭数据库连接        self.client.close()    def process_item(self, item, spider):        self.zfdb[self.collection].insert({"title": item["title"].strip()})        return item


640?

保存到 MySQL

from sqlalchemy import create_engine, Column, Integer, String, BIGINT, ForeignKey, UniqueConstraint, Index, and_, \    or_, inspectfrom sqlalchemy.orm import sessionmaker, relationship, contains_eagerclass MysqlPipeline(object):    MYSQL_URI = 'mysql+pymysql://username:password@localhost:3306/db_name'    # echo 为 True 将会输出 SQL 原生语句    engine = create_engine(MYSQL_URI, echo=True)    from sqlalchemy.ext.declarative import declarative_base    Base = declarative_base()    # 创建单表    class Movie(Base):        __tablename__ = 'movies'        id = Column(BIGINT, primary_key=True, autoincrement=True)        title = Column(String(200))    # 初始化数据库    def init_db(self):        self.Base.metadata.create_all(self.engine)    # 删除数据库    def drop_db(self):        self.Base.metadata.drop_all(self.engine)    def open_spider(self, spider):  # 爬虫启动时调用,连接到数据库        self.init_db()        Session = sessionmaker(bind=self.engine)        self.session = Session()    def process_item(self, item, spider):        new_movie = self.Movie(title=item["title"].strip())        self.session.add(new_movie)        self.session.commit()        return item


640?


在写好相关的 pipeline 之后,需要在 settings.py 中启用相关的 pipeline,后面的数字为调用的优先级,数字是0-1000,你可以自定义。你可以所有格式都保存,也可以注释掉其他,值保留一个。


ITEM_PIPELINES = {    'doubanTop250.pipelines.MongoPipeline': 300,    'doubanTop250.pipelines.MysqlPipeline': 301,    'doubanTop250.pipelines.CsvPipeline': 302,    'doubanTop250.pipelines.JsonPipeline': 303,}

瞎比比

数据保存就说到这里了,后台回复“scrapy初体验”获取源码,为什么获取源码的关键词都一样呢?因为每推一篇文章,代码都会升级。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值