基於終端指令的持久化存儲
- 保證爬蟲文件的parse方法中有可迭代類型對象(一般爲列表or字典)的返回,該返回值能夠經過終端指令的形式寫入指定格式的文件中進行持久化操做;css
- 執行輸出指定格式進行存儲:將爬取到的數據寫入不一樣格式的文件中進行存儲html
scrapy crawl 爬蟲名稱 -o xxx.json
scrapy crawl 爬蟲名稱 -o xxx.xml
scrapy crawl 爬蟲名稱 -o xxx.csv
基於管道的持久化存儲
- scrapy框架中已經爲咱們專門集成好了高效、便捷的持久化操做功能,咱們直接使用便可:python
- items.py : 數據結構模板文件,定義數據屬性;mysql
- pipelines.py : 管道文件,接受item類型的數據,進行持久化操做;redis
- 持久化流程:sql
- 在爬蟲文件中獲取到數據後,將數據封裝到 items對象中;數據庫
- 經過 yield 關鍵字將items對象提交給pipelines管道進行持久化操做;json
- 在管道文件中的process_item方法中接收爬蟲文件提交過來的item對象,而後編寫持久化存儲的代碼將item對象存儲的數據進行持久化存儲;數據結構
- settings.py文件中開啓管道:框架
ITEM_PIPELINES = {
'qiubaiPro.pipelines.QiubaiproPipelineByRedis': 300, }
- 持久化存儲示例:
- 將糗事百科首頁中的段子和做者數據爬取下來,而後進行持久化存儲
- 爬蟲文件:
# -*- coding: utf-8 -*- import scrapy from secondblood.items import SecondbloodItem class QiubaidemoSpider(scrapy.Spider): name = 'qiubaiDemo' allowed_domains = ['www.qiushibaike.com'] start_urls = ['http://www.qiushibaike.com/'] def parse(self, response): odiv = response.xpath('//div[@id="content-left"]/div') for div in odiv: # xpath函數返回的爲列表,列表中存放的數據爲Selector類型的數據。咱們解析到的內容被封裝在了Selector對象中,須要調用extract()函數將解析的內容從Selecor中取出。 author = div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first() author = author.strip('\n')#過濾空行 content = div.xpath('.//div[@class="content"]/span/text()').extract_first() content = content.strip('\n')#過濾空行 #將解析到的數據封裝至items對象中 item = SecondbloodItem() item['author'] = author item['content'] = content yield item#提交item到管道文件(pipelines.py)
- items.py:
import scrapy class SecondbloodItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() author = scrapy.Field() #存儲做者 content = scrapy.Field() #存儲段子內容
- 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 class SecondbloodPipeline(object): #構造方法 def __init__(self): self.fp = None #定義一個文件描述符屬性 #下列都是在重寫父類的方法: #開始爬蟲時,執行一次 def open_spider(self,spider): print('爬蟲開始') self.fp = open('./data.txt', 'w') #由於該方法會被執行調用屢次,因此文件的開啓和關閉操做寫在了另外兩個只會各自執行一次的方法中。 def process_item(self, item, spider): #將爬蟲程序提交的item進行持久化存儲 self.fp.write(item['author'] + ':' + item['content'] + '\n') return item #結束爬蟲時,執行一次 def close_spider(self,spider): self.fp.close() print('爬蟲結束')
- settins.py
#開啓管道 ITEM_PIPELINES = { 'secondblood.pipelines.SecondbloodPipeline': 300, #300表示爲優先級,值越小優先級越高 }
基於mysql的管道存儲
- 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 #導入數據庫的類 import pymysql class mysqlPipeLine(object): conn = None #mysql的鏈接對象聲明 cursor = None#mysql遊標對象聲明 def open_spider(self,spider): print('開始爬蟲') #連接數據庫 self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='123456',db='qiubai') #編寫向數據庫中存儲數據的相關代碼 def process_item(self, item, spider): #1.連接數據庫 #2.執行sql語句 sql = 'insert into qiubai values("%s","%s")'%(item['author'],item['content']) self.cursor = self.conn.cursor() #執行事務 try: self.cursor.execute(sql) 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()
- settings.py
# 開啓管道,自定義管道向不用的數據庫存儲數據 # 300是優先級,數字越小,優先級越高 ITEM_PIPELINES = { 'boss.pipelines.BossPipeline': 300, 'boss.pipelines.mysqlPipeLine': 301, }
基於redis的管道存儲
修改redis.window.conf配置文件 保護模式改成no bind 0.0.0.1
- pipelines.py文件
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'] } import json print(88888888888) # self.conn.lpush('jobInfo',json.dumps(dic)) # 寫入redis self.conn.lpush('jobInfo_1',json.dumps(dic)) # 存入redis的數據須要json return item def open_spider(self, spider): # 建立連接對象 self.conn = Redis(host='127.0.0.1',port=6379) print(self.conn) #[注意]必定要保證每個管道類的process_item方法要有返回值
- setting.py文件
# 開啓管道,自定義管道向不用的數據庫存儲數據 # 300是優先級,數字越小,優先級越高 ITEM_PIPELINES = { 'boss.pipelines.RedisPipeLine': 301, }