scrapt---持久化方案

两种方案,第二种常用

第一种:

       1.  解析函数中parse,要return [{},{},{}]-------- parse必须有return值,必须是列表套字典形式--->使用命令,可以保存到json格式中

       2.执行如下命令  ----cmd

   scrapy crawl 创建的爬虫名字 -o 文件名(json,pickle,csv结尾)
例子:
   scrapy crawl baidu -o baidu.json

方案二:使用pipline  常用的,管道形式,可以同时存到多个位置的

        1 在items.py中写一个类[相当于写django的表模型],继承scrapy.Item

        2. 在类中写属性,写字段,所有字段都是scrapy.Field类型
            title = scrapy.Field()

class CnblogsItem(scrapy.Item):       类名随便起
    title = scrapy.Field()            title,desc。。。。。。 属于字段名
    desc = scrapy.Field() 
    author_img = scrapy.Field()
    author_name = scrapy.Field()
    url = scrapy.Field()
    concent = scrapy.Field()

        3.在pipline.py中写代码,写一个类:open_spide,close_spider,process_item

                

        -open_spide:开启爬虫会触发
    	-close_spider:爬完会触发
        -process_ite:每次要保存一个对象会触发
class MenusqlPipeline:
    def open_spide(self,spider):
        self.connection = pymysql.connect(host='127.0.0.1',user='root',password= 'xxx', database='scrapy_db',port= 3306, charset='utf8')
        self.cursor = self.connection.cursor()  # 获取SQL执行器(游标)
        print('连接上了')
    def process_item(self, item, spider):   #有特殊字段一定要加反引号
        sql = "insert into cnblogs(title,`desc`,author_img,author_name,url,concent) values(%s,%s,%s,%s,%s,%s)"
        # 注意 params添加的顺序要和sql语句插入的顺序一致,否则会出现错位甚至插入失败的情况
        params = list()
        params.append(item['title'])
        params.append(item['desc'])
        params.append(item['author_img'])
        params.append(item['author_name'])
        params.append(item['url'])
        params.append(item['concent'])
        self.cursor.execute(sql, tuple(params))  # 4、执行SQL语句
        self.connection.commit()  # 5、提交到数据库
        print('提交到数据库')
        return item
    def close_spider(self,spider):
        self.cursor.close()
        self.connection.close()

         4.配置文件配置   -------将你在      pipline.py中自己定义的类,在setting.py中配置

ITEM_PIPELINES = {
           "firstscrapy.pipelines.FirstscrapyFilePipeline": 300,  # 数字越小,优先级越高
        }

        5.在爬虫类中调用

        注意:

          1.item = CnblogsItem()   定义在for内部,每次都是一个新对象,在items.py中的定义的类。

          2.item['title'] = title     一定要用括号这种形式写

          3.yield item      最后一定要写yield item,才能将item提交给管道,然后保存数据库

import scrapy
from myfilescrapy import pipelines
from myfilescrapy.items import CnblogsItem
from scrapy import Request
class CnblorsSpider(scrapy.Spider):
    name = "cnblors"      #创建爬虫时的名字
    allowed_domains = ["www.cnblogs.com"]     #能够访问的域
    start_urls = ["https://www.cnblogs.com"]  #爬取的初始地址

    def parse(self, response):
        article_list = response.xpath('//*[@id="post_list"]/article')
        for article in article_list:
            item = CnblogsItem()  # 定义在for内部,每次都是一个新对象    在items.py中的定义的类
            title = article.xpath('./section/div/a/text()').extract_first()
            author_img = article.xpath('./section/div/p//img/@src').extract_first()
            desc = article.xpath('./section/div/p/text()').extract()
            '''
            ['\n                        ', '\n                    〇、前言 日常开发中经常会遇到数据统计,特别是关于报表的项目。数据处理的效率和准确度当然是首要关注点。 本文主要介绍,如何通过 Parallel 来并行处理数据,并组合 ConcurrentBag 集合,来将处理效率达到高点的同时,也能确保数据的准确。 一、ConcurrentBag 简 ...\n                ']
            '''
            real_desc = desc[0].replace('\n', '').replace(' ', '')
            if real_desc:
                desc = real_desc
            else:
                real_desc = desc[1].replace('\n', '').replace(' ', '')
                desc = real_desc
            author_name = article.xpath('./section/footer/a/span/text()').extract_first()
            url = article.xpath('./section/div/a/@href').extract_first()
            item['title'] = title
            item['desc'] = desc
            item['author_img'] = author_img
            item['author_name'] = author_name
            item['url'] = url
            yield Request(url=url,callback=self.parse_deil,meta={'item':item})
        # 获取下一次地址    

        next = 'https://www.cnblogs.com/'+response.xpath('//div[contains(@class,"pager")]/a[last()]/@href').extract_first()
        yield Request(url=next,callback=self.parse)

    def parse_deil(self,response):
        # cnblogs_post_body
        item= response.meta.get('item')
        concent = str(response.xpath('//div[contains(@class,"post")]').extract_first())
        item['concent'] = concent
        yield item      #最后一定要写yield item,才能将item提交给管道,然后保存数据库

你可能感兴趣的:(sqlite,数据库)