欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Scrapy持久化存储

程序员文章站 2022-07-05 15:34:19
基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作; 执行输出指定格式进行存储:将爬取到的数据写入不同格式的文件中进行存储 基于管道的持久化存储 scrapy框架中已经为我们专门集成好 ......

基于终端指令的持久化存储

  保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作;

执行输出指定格式进行存储:将爬取到的数据写入不同格式的文件中进行存储

    scrapy crawl 爬虫名称 -o xxx.json
    scrapy crawl 爬虫名称 -o xxx.xml
    scrapy crawl 爬虫名称 -o xxx.csv

基于管道的持久化存储

  scrapy框架中已经为我们专门集成好了高效、便捷的持久化操作功能,我们直接使用即可:

       items.py : 数据结构模板文件,定义数据属性;

    pipelines.py : 管道文件,接受item类型的数据,进行持久化操作;

持久化流程:

  1. 在爬虫文件中获取到数据后,将数据封装到 items对象中;
  2. 通过 yield 关键字将items对象提交给pipelines管道进行持久化操作;
  3. 在管道文件中的process_item方法中接收爬虫文件提交过来的item对象,然后编写持久化存储的代码将item对象存储的数据进行持久化存储;

settings.py文件中开启管道:

item_pipelines = {
    'qiubaipro.pipelines.qiubaipropipelinebyredis': 300,
}

终端持久化存储示例:

  将糗事百科首页中的段子和作者数据爬取下来,然后进行持久化存储

爬虫程序

# -*- coding: utf-8 -*-
import scrapy


class qiubaispider(scrapy.spider):
    name = 'qiubai'
    # allowed_domains = ['www.qiushibaike.com']
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        div_list = response.xpath('//div[@id="content-left"]/div')
        all_data = []
        # xpath返回的列表元素类型为selector类型
        for div in div_list:
            # title = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()')[0].extract()
            author = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
            content = div.xpath('./a[1]/div/span/text()').extract_first()

            dic = {
                'author': author,
                'content': content
            }

            all_data.append(dic)
        # 基于终端指令的持久化存储:可以通过终端指令的形式将parse方法的返回值中存储的数据进行本地磁盘的持久化存储
        return all_data

settings

bot_name = 'qiubaipro'
user_agent = 'mozilla/5.0 (macintosh; intel mac os x 10_12_0) applewebkit/537.36 (khtml, like gecko) chrome/68.0.3440.106 safari/537.36'
spider_modules = ['qiubaipro.spiders']
newspider_module = 'qiubaipro.spiders'
robotstxt_obey = false

执行:

scrapy crawl qiubai -o qiubai.csv

Scrapy持久化存储

执行完之后的结果:

Scrapy持久化存储

管道持久化存储示例:

爬取boss直聘网中python爬虫岗位的职位名称,薪资,公司名称

爬虫程序

# -*- coding: utf-8 -*-
import scrapy
from bosspro.items import bossproitem


class bossspider(scrapy.spider):
    name = 'boss'
    allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.zhipin.com/job_detail/?query=python爬虫&scity=101010100&industry=&position=']

    def parse(self, response):
        li_list = response.xpath('//div[@class="job-list"]/ul/li')
        for li in li_list:
            title = li.xpath('.//div[@class="info-primary"]/h3[@class="name"]/a/div/text()').extract_first()
            salary = li.xpath('.//div[@class="info-primary"]/h3[@class="name"]/a/span/text()').extract_first()
            company = li.xpath('.//div[@class="company-text"]/h3/a/text()').extract_first()

            # 实例化一个item类型的对象
            item = bossproitem()
            # 将解析到的数据存储到item对象中
            item["title"] = title
            item["salary"] = salary
            item["company"] = company

            # 将item对象提交给管道进行持久化存储
            yield item

items

# -*- coding: utf-8 -*-

# define here the models for your scraped items
#
# see documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class bossproitem(scrapy.item):
    # define the fields for your item here like:
    # name = scrapy.field()
    title = scrapy.field()
    salary = scrapy.field()
    company = scrapy.field()

pipelines

# -*- coding: utf-8 -*-

# define your item pipelines here
#
# don't forget to add your pipeline to the item_pipelines setting
# see: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

# 管道文件:需要接收爬虫文件提交过来的数据,并对数据进行持久化存储.(io操作)
class bosspropipeline(object):
    fp = none
    # 只会被执行一次(开始爬虫的时候执行一次)
    def open_spider(self,spider):
        print("开始爬虫")
        self.fp = open('./job.txt','w',encoding='utf-8')
    # 爬虫文件每提交一次,该方法就会被调用一次
    def process_item(self, item, spider): #300表示为优先级,值越小优先级越高
        self.fp.write(item['title'] + "\t" + item['salary'] + '\t' + item['company'] + '\n')
        return item
    # 结束爬虫时执行
    def close_spider(self,spider):
        self.fp.close()
        print("爬虫结束")

# 注意:默认情况下,管道机制并没有开启,需要手动在配置文件中进行开启

# 使用管道进行持久化的流程:
#   1.获取解析到的数据
#   2.将解析的数据存储到item对象(item类中进行相关属性的声明)
#   3.通过yield关键字将item提交到管道
#   4.管道文件中进行持久化存储代码的编写(process_item)
#   5.在配置文件中开启管道

settings

#开启管道
item_pipelines = {
    'secondblood.pipelines.secondbloodpipeline': 300, #300表示为优先级,值越小优先级越高
}

执行:

scrapy crawl boss --nolog

Scrapy持久化存储

Scrapy持久化存储

基于mysql的持久化存储

pipelines

import pymysql
class mysqlpipeline(object):
    conn = none
    cursor = none
    def open_spider(self,spider):
        self.conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='', db='spider')
        print(self.conn)
    def process_item(self, item, spider):
        self.cursor = self.conn.cursor()
        sql = 'insert into boss values("%s","%s","%s")'%(item['title'],item['salary'],item['company'])
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except exception as e:
            print (e)
            self.conn.rollback()

    def close_spider(self,spider):
        self.cursor.close()
        self.conn.close()

settings

# 开启管道,自定义管道向不用的数据库存储数据
# 300是优先级,数字越小,优先级越高
 
item_pipelines = {
   'boss.pipelines.bosspipeline': 300,
   'boss.pipelines.mysqlpipeline': 301,
}

执行爬虫程序,并去数据库中查看数据

Scrapy持久化存储

基于redis管道存储

 pipelines

from redis import redis
class redispipeline(object):
    conn = none
    def process_item(self,item,spider):
        dic = {
            "title":item["title"],
            "salary":item["salary"],
            "company":item["company"]
        }
        self.conn.lpush("jobinfo",json.dumps(dic))
    def open_spider(self,spider):
        self.conn = redis(host='127.0.0.1',port=6379)
        print (self.conn)

settings

item_pipelines = {
   #'bosspro.pipelines.bosspropipeline': 300,
   #'bosspro.pipelines.mysqlpipeline': 301,
   'bosspro.pipelines.redispipeline': 302,
}

执行代码并且查看redis中的数据

Scrapy持久化存储

redis已经存在数据了,因为编码问题所以不显示中文.