scrapy的持久化相关
终端指令的持久化存储
保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作。
需求是:将糗百首页中段子的内容和标题进行爬取
新建项目流程
cmd中 # 建立项目 scrapy startproject qiubaiDemo # 进入项目名称 cd qiubaiDemo # 创建应用和起始url // 网址先随便先 一会编辑时候在修改 scrapy genspider qiubai www.xxx.com # 编辑后运行时候执行 scrapy crawl 应用名称
settings 文件
19行: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' #伪装请求载体身份 22行:ROBOTSTXT_OBEY = False #可以忽略或者不遵守robots协议
qiubai文件编辑内容为
# -*- coding: utf-8 -*- import scrapy class QiubaiSpider(scrapy.Spider): name = 'qiubai' allowed_domains = ['www.xxx.com'] start_urls = ['https://www.qiushibaike.com/text/'] def parse(self, response): div_list = response.xpath('//div[@id="content-left"]/div') all_data = [] for div in div_list: title = 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 = { 'title': title, 'content': content } all_data.append(dic) print(all_data) # 基于终端指令的持久化存储:可以通过终端指令的形式将parse方法的返回值中存储的数据进行本地磁盘的持久化存储 return all_data
执行爬虫应用
scrapy crawl qiubai -o 糗百.csv
* 执行输出指定格式进行存储:将爬取到的数据写入不同格式的文件中进行存储
scrapy crawl 爬虫名称 -o xxx.json scrapy crawl 爬虫名称 -o xxx.xml scrapy crawl 爬虫名称 -o xxx.csv
基于管道的持久化存储
scrapy框架中已经为我们专门集成好了高效、便捷的持久化操作功能,我们直接使用即可。要想使用scrapy的持久化操作功能,我们首先来认识如下两个文件:
items.py:数据结构模板文件。定义数据属性。 pipelines.py:管道文件。接收数据(items),进行持久化操作。 持久化流程: 1.爬虫文件爬取到数据后,需要将数据封装到items对象中。 2.使用yield关键字将items对象提交给pipelines管道进行持久化操作。 3.在管道文件中的process_item方法中接收爬虫文件提交过来的item对象,然后编写持久化存储的代码将item对象中存储的数据进行持久化存储 4.settings.py配置文件中开启管道
将boos直聘的数据爬取下来,然后进行持久化存储
mysql篇
# -*- coding: utf-8 -*- import scrapy from boosPro.items import BoosproItem class BoosSpider(scrapy.Spider): name = 'boos' allowed_domains = ['www.xxx.com'] start_urls = [ 'https://www.zhipin.com/job_detail/?query=python%E7%88%AC%E8%99%AB&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 = BoosproItem() # 将解析到的数据值存储到item对象中:why? item['title'] = title item['salary'] = salary item['company'] = company # 将item对象提交给管道进行持久化存储 yield item
import scrapy class BoosproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() salary = scrapy.Field() company = scrapy.Field()
# 注意:默认情况下,管道机制并没有开启.需要手动在配置文件中进行开启 # 使用管道进行持久化存储的流程: # 1.获取解析到的数据值 # 2.将解析的数据值存储到item对象(item类中进行相关属性的声明) # 3.通过yield关键字将item提交到管道 # 4.管道文件中进行持久化存储代码的编写(process_item) # 5.在配置文件中开启管道 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='123', 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() return item def close_spider(self, spider): self.cursor.close() self.conn.close()
# 加入身份伪装 USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' # 关闭root协议 ROBOTSTXT_OBEY = False # 开启管道 ITEM_PIPELINES = { 'boosPro.pipelines.BoosproPipeline': 300, 'boosPro.pipelines.mysqlPipeLine': 301, }
redis篇
在刚才代码中修改了settings文件和pipelines.py
# -*- 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 BoosproPipeline(object): fp = None # 只会被执行一次(开始爬虫的时候执行一次) def open_spider(self, spider): print('开始爬虫!!!') self.fp = open('./boos.txt', 'w', encoding='utf-8') # 爬虫文件没提交一次item,该方法会被调用一次 def process_item(self, item, spider): self.fp.write(item['title'] + "\t" + item['salary'] + '\t' + item['company'] + '\n') return item def close_spider(self, spider): print('爬虫结束!!!') self.fp.close() # 注意:默认情况下,管道机制并没有开启.需要手动在配置文件中进行开启 # 使用管道进行持久化存储的流程: # 1.获取解析到的数据值 # 2.将解析的数据值存储到item对象(item类中进行相关属性的声明) # 3.通过yield关键字将item提交到管道 # 4.管道文件中进行持久化存储代码的编写(process_item) # 5.在配置文件中开启管道 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='123', 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() return item def close_spider(self, spider): self.cursor.close() self.conn.close() from redis import Redis import json 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)) return item def open_spider(self, spider): self.conn = Redis(host='127.0.0.1', port=6379) print(self.conn) # [注意]一定要保证每一个管道类的process_item方法要有返回值
ITEM_PIPELINES = { # 'boosPro.pipelines.BoosproPipeline': 300, # 'boosPro.pipelines.mysqlPipeLine': 301, 'boosPro.pipelines.RedisPipeLine': 302, }
[注意]一定要保证每一个管道类的process_item方法要有返回值
执行爬虫程序
登录redis-cli 查看数据
lrange jobInfo 0 -1 # type 是list