zoukankan      html  css  js  c++  java
  • scrapy爬取数据保存csv、mysql、mongodb、json

    目录

    • 前言

    • Items

    • Pipelines

    前言

    用Scrapy进行数据的保存进行一个常用的方法进行解析

    Items

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

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

    Pipelines

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

    保存到 Json

    import json
    class 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
    View Code
     

    保存到 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
    View Code

    保存到 MongoDB

    from pymongo import MongoClient
    import os
    base_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
     

    保存到 MySQL

    from sqlalchemy import create_engine, Column, Integer, String, BIGINT, ForeignKey, UniqueConstraint, Index, and_, 
        or_, inspect
    from sqlalchemy.orm import sessionmaker, relationship, contains_eager
    class 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

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

    ITEM_PIPELINES = {
        'doubanTop250.pipelines.MongoPipeline': 300,
        'doubanTop250.pipelines.MysqlPipeline': 301,
        'doubanTop250.pipelines.CsvPipeline': 302,
        'doubanTop250.pipelines.JsonPipeline': 303,
    }
  • 相关阅读:
    数字化航电平台 3D 可视化,图扑助力珠海航展国产民机航电平台品牌发布
    20211123
    多叉树操作
    ILjava/lang/String;)Ljava/util/List
    Fiddler使用总结
    java stream map对于 key重复的处理方式,上述代码表示,重复的话,取信值
    java中map里面的key按我们插入进去的顺序输出
    IntelliJ IDEA 中自动去除未使用的引入(Unused import statement)
    加redis锁
    LambdaQueryWrapper 查distinct数据
  • 原文地址:https://www.cnblogs.com/yunlongaimeng/p/10266361.html
Copyright © 2011-2022 走看看