• scrapy框架_3持久化存储


    scrapy持久化存储

    基于终端的存储

      - 只可以将parse方法的返回值存储到本地的文本文件中
      - 只支持json jsonlines   jl  csv xml   marshal  pickle这几种文本
      - 好处:简洁,高效
      - 缺点:局限性比较强(数据只可以存储到指定后缀的文本文件中)
      - 指令:scrapy  crawl  名字  -o  地址           
      - 指令例子如下   
      scrapy  crawl  name -o  ./fliePath.csv 
    

    - 基于管道的存储

      - 编程流程:
                1. 数据解析
                2. 在item类中定义相关属性
                3. 将解析的数据封装到item类型的对象
                4. 将item类型的对象提交到管道进行持久化存储的操作
                5. 在管道类的process_item中要将其接收到item对象中存储的数据进行持久化存储操作
                6. 在配置文件中开启管道
      - 好处:
                - 通用性强
    

    面试题:将爬取到的数据存储本地一份,一份到数据库,如何实现?

      - 管道文件中一个管道类对应的是将数据存储到一种平台
      - 爬虫文件提交的item只会给管道文件中第一个被执行的管道类接收
      - process_item方法中的return item 表示将item传递给下一个即将被执行的管道类
    

    糗事百科案例_持久化存储

    spiders文件夹下的 名字为first.py的文件

    # -*- coding: utf-8 -*-
    import scrapy
    from TestOne.items import TestoneItem
    from scrapy.spiders import CrawlSpider
    class FirstSpider(scrapy.Spider):
    
        #爬虫文件的名称:就是爬虫源文件唯一标识
        name = 'first'
        #允许的域名:用来限制start_urls那些url可以进行请求发送
        # allowed_domains = ['www.baidu.com','https://www.sogou.com/',]
        #启始url的列表:该列表存放的url会被scrapy自动请求发送
        start_urls = ['https://www.qiushibaike.com/text/',]
    
        #用于数据解析:response参数表示就是请求成功后对应的响应对象
    
    
    
        def parse(self, response):
            # 存储所有解析到的数据
            all_data = []
            div_list = response.xpath('//*[@id="content"]/div/div[2]/div')
            for div in div_list:
                # xpath返回的是列表,但是列表元素一定是Selector类型的对象
                # extract可以将Selector对象中的data参数存储的字符串提取出来
                # 第一种写法
                author = div.xpath('./div[1]/a[2]/h2//text()')[0].extract()
                # 第二种写法
                # author = div.xpath('./div[1]/a[2]/h2//text()').extract_first()
    
                # 列表调用了extract之后,则表示将列表中的Selector对象中的data对的的字符串提取出来
                content = div.xpath('./a/div/span//text()').extract()
    
                # 格式化
                content = ' '.join(content).replace('
    ', '')
                item=TestoneItem()
                item['author']=author
                item['content']=content
                yield  item#将item提交给了管道
    
    

    item文件

    #管道的文件
    import scrapy
    
    
    class TestoneItem(scrapy.Item):
        author=scrapy.Field()
        content=scrapy.Field()
    

    pipelines.py文件

    import  pymysql
    #记得在数据库先建好表
    class TestonePipeline(object):
        fp=None
        #重写父类的一个方法.该方法只在开始爬虫的时候调用一次
        def open_spider(self,spider):
            print('开始爬虫....')
            self.fp=open('./qiubai.txt','w',encoding='utf-8')
        #专门处理item类型对象的
        #该方法可以接收到爬虫文件提交过来的item对象
        #该方法每次接收到一个item会被调用一次
        def process_item(self, item, spider):
            author =item['author']
            content= item['content']
            self.fp.write(author+':'+content+'
    ')
            return item
    
        def close_spider(self,spider):
            print('结束爬虫....')
            self.fp.close()
    
    class mysqlPileLine(object):
        conn=None
        cursor=None
        def open_spider(self,spider):
            print('开始写数据库')
                #host数据库ip地址  port端口   user账户 password 密码  db库
            self.conn=pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='root',db='qiubai')
        def process_item(self,item, spider):
            self.cursor=self.conn.cursor()
            try:
                #sql语句格式化输出
                self.cursor.execute('insert into qiubai value ("%s","%s")'%(item["author"],item["content"]))
                self.conn.commit()
            except Exception as e:
                print(e)
                self.conn.rollback()
            return  item
        def close_spider(self,spider):
            print('数据库结束!!!!!!')
            self.cursor.close()
            self.conn.close()
    
    

    setting配置文件

    BOT_NAME = 'TestOne'
    
    SPIDER_MODULES = ['TestOne.spiders']
    NEWSPIDER_MODULE = 'TestOne.spiders'
    
    ITEM_PIPELINES = {
       'TestOne.pipelines.TestonePipeline': 300,
       'TestOne.pipelines.mysqlPileLine':200
        #300表示优先级,数值越小优先级越高
    }
    # Crawl responsibly by identifying yourself (and your website) on the user-agent
    #UA伪装
    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'
    
    # Obey robots.txt rules
    #robots协议是否遵从
    ROBOTSTXT_OBEY = False
    #显示指定类型的日志信息
    LOG_LEVEL="ERROR"
    
    
  • 相关阅读:
    leetcode16 3-Sum
    leetcode679:24Game
    leetcode621 贪心:任务安排
    SpringMVC中的Controller默认单例
    O(n)复杂度求没有出现的数字(leetcode448)
    SpringBoot获取ApplicationContext
    Largest Number(leetcode 179)
    使用免费ip代理进行投票
    Oracle分页
    Oracle JDBC配置
  • 原文地址:https://www.cnblogs.com/SkyRabbit/p/13715329.html
Copyright © 2020-2023  润新知