• Scrapy数据持久化


    piplines的使用

    取消setings.py文件内管道的注释,开启数据管道,使得爬取到的数据可以传送过来。

    2019-08-24_20-01-06

    初始代码解释

    2019-08-24_20-14-18

    利用重写spider的方法实现功能

    2019-08-24_20-25-50

    # 初始化SpiderdmPipeline类时调用一次
    def __init__(self):
        # 创建数据库的连接对象
        # 数据表的创建
        pass
    
    # 启动爬虫时调用一次
    def open_spider(self, spider):
        # 同__init__方法,实现爬虫开始时,只需要执行一次的操作。
        pass
    
    # 每传送一条数据就掉用一次
    def process_item(self, item, spider):
        # 实现处理每一条数据保存和处理的代码
        # 或者直接交给下一个管道处理
        return item
    
    # 关闭爬虫时掉用一次
    def close_spider(self, spider):
        # 断开数据库连接
        # 释放资源等,在关闭爬虫前需要的操作。
        pass
    

    多个管道处理实现数据流水线处理

    创建SpiderdmPipeline_1类

    2019-08-24_20-50-17

    注册SpiderdmPipeline_1类并设置与资源调度器的距离

    2019-08-24_20-55-56

    SpiderdmPipeline_1 先拿到数据后,处理item数据。return 一个item给下一个比它距离数值更大的下一个管道处理(SpiderdmPipeline),注意return返回的只是Item类型的数据不一定要是item。

    保存数据的方式

    使用pymysql保存到MySQL

    安装pymysql库,启动MySQL服务

    pip --default-timeout=100  install pymysql -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    

    创建数据库

    import pymysql
    
    #连接数据库
    db = pymysql.connect(host='localhost',user='root',password='123456',port=3306,charset='utf8') 
    
    #获取操作数据库的游标
    cur = db.cursor() 
    
    #创建数据库
    cur.execute('create database if not exists testdb')
    
    #提交sql语句到数据库执行
    db.commit() 
    #关闭游标和数据库连接
    cur.close() 
    db.close()
    

    操作数据库

    import pymysql
    
    db = pymysql.connect(host='localhost',user='root',password='123456',db='testdb',port=3306,charset='utf8')
    
    #获取操作数据库的游标
    cur = db.cursor() 
    
    #创建数据表
    sql = '''create table if not exists pytable(
      id int(11) not null auto_increment,
      name varchar(11) null,
      age int(3) null,
      primary key (id)
    )engine=innodb'''
    cur.execute(sql)
    
    #增
    # 插入单条数据
    result = cur.execute('insert into pymysqltest(name,age) values (%s,%s)',['张三',18])
    # 多单条数据
    result = cur.executemany('insert into pymysqltest(name,age) values (%s,%s)',[['张三',18],['李四',19],['王五',20]]) 
    
    #删
    result = cur.execute('delete from `pymysqltest` where `age`=%s or `name`=%s',[18,'李四'])
    
    #改
    result = cur.execute('update `pymysqltest` set `age`=%s where `name`=%s ',[18,'李四'])
    
    #查
    # 返回获得的数据数量
    # result = cur.execute('select * from  `pymysqltest` ') 
    # result = cur.execute('select * from  `pymysqltest` where `age`=%s ',[18])
    # 获取游标获得全部数据的元组 tuple
    # data = cur.fetchall() 
    # # print(type(data))
    # for e in data: #遍历输出数据
    #     print(e)
    #     print(e[0],e[1],e[2])
    
    #提交sql语句到数据库执行
    db.commit()
    
    cur.close() 
    db.close()
    

    保存数据到MongoDB

    安装pymongo库,启动mongodb服务

    pip --default-timeout=100  install pymongo -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    

    在setings里面配置MongoDB的连接信息(名称可以自己取,建议都大写)

    #mongodb 连接信息
    MONGODB_HOST = 'localhost' #ip地址
    MONGODB_PORT = 27017 #端口
    MONGODB_DBNAME = 'TestMongo' #数据库名称
    MONGODB_DOCNAME = 'test' #表名
    

    2019-08-25_15-11-43

    添加访问头User-Agent,模拟浏览器访问网页。由于百度首页不让爬,所以需要设置不不遵循robots协议。

    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    
    ROBOTSTXT_OBEY = False
    

    2019-08-25_17-17-21

    设置在items里面定义需要发送的字段。

    # 定义需要发送的字段
    data = scrapy.Field()
    

    2019-08-25_17-22-31

    写发送数据给pipeline的代码

    2019-08-25_17-30-57

    在调用setings里面的配置信息,在pipelines里面写操作MongoDB的代码(确保pipeline已开启)

    2019-08-25_17-41-09

    import pymongo
    from spiderDM.settings import *
    
    
    class SpiderdmPipeline(object):
    
        # 初始化变量
        def __init__(self):
            # MongoDB主机IP
            self.MG_HOST = MONGODB_HOST
            # MongoDB端口
            self.MG_PORT = MONGODB_PORT
            # 操作的数据库
            self.MG_DBNAME = MONGODB_DBNAME
            # 操作的数据表
            self.MG_TABLE = MONGODB_DOCNAME
    
        def open_spider(self, spider):
            # 创建链接,不写默认值为'localhost',27017
            self.connection = pymongo.MongoClient(host=self.MG_HOST, port=self.MG_PORT)
            # 获得操作数据表的对象
            self.table = self.connection.get_database(self.MG_DBNAME).get_collection(self.MG_TABLE)
    
        def process_item(self, item, spider):
            data = item["data"]
            # 插入数据
            self.table.insert_one(data)
            # 查询插入的数据
            result = self.table.find({"name": "小名"})
            # 遍历查询的数据
            for e in result:
                print(e)
    
            return item
    
        def close_spider(self, spider):
            # 关闭与MongoDB连接
            self.connection.close()
    

    运行爬虫

    2019-08-25_17-55-09

    保存为其他文件类型

    读写CSV
    import csv
    
    # 写入CSV
    # newline='' 使写入一行数据时不自动换行,writ.writerow()写入自带换行。
    fo = open('./dataPackage/listToCsv.csv','w',encoding='utf8',newline='')
    # dialect='excel'设置存储的格式
    writ = csv.writer(fo,dialect='excel')
    for i in range(10):
        # 0,1,2,3,4
        writ.writerow(list(range(i,i+5)))
    fo.close()
    
    
    # 读取CSV
    fr = open('./dataPackage/listToCsv.csv','r',encoding='utf-8')
    # 读取csv文件数据
    data = csv.reader(fr)
    for e in data:
        print(e)
    fr.close()
    
    with open('./dataPackage/list_to_csv.csv','w',encoding='utf-8') as f:
        for i in range(10):
            # 写入的数据只能是字符串
            data = ','.join(map(lambda num: str(num),list(range(i,i+5))))
            f.write(data+'
    ')
    
    with open('./dataPackage/list_to_csv.csv','r',encoding='utf-8') as f:
        data = f.readlines()
        for line in data:
            print(line)
    
    #以json格式输出
    from scrapy.exporters import JsonItemExporter #[所有数据]
    #以jl格式输出
    #from scrapy.exporters import JsonLinesItemExporter #一条数据一行
    #以csv格式输出 
    #from scrapy.exporters import CsvItemExporter #保存为csv
    
    def __init__(self):
        self.file = open('job.json','wb')
    
        self.export = JsonItemExporter(self.file,encoding='utf8',ensure_ascii=False)
        self.export.start_exporting()
    
    def close_spider(self,spider):
        self.export.finish_exporting()
        self.file.close()
    
    def process_item(self,item,spider):
        self.export.export_item(item)
        return item
        def open_spider(self, spider):
    
  • 相关阅读:
    Java基础之IO流,使用File类以树形结构打印指定文件目录
    Java基础之IO流,以字节流的方式操作读写文件FileOutputStream和FileInputStream的使用
    Java基础之IO流,自定义字节流缓冲区装饰类(模仿)
    Java基础之IO流,转换流应用InputStreamReader,OutputStreamWriter
    碰撞处理游戏的原型
    flash中物体运动基础之六方向与角度
    flash中物体运动基础之七碰撞处理
    推导坐标旋转公式
    flash中物体运动基础之一匀速运动
    flash中物体运动基础之五障碍物
  • 原文地址:https://www.cnblogs.com/studyNotesSL/p/11409552.html
Copyright © 2020-2023  润新知