基於終端指令的持久化存儲 保證爬蟲文件的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類型的數據,進行持久化操作;
持久化流程:
- 在爬蟲文件中獲取到數據後,將數據封裝到 items對象中;
- 通過 yield 關鍵字將items對象提交給pipelines管道進行持久化操作;
- 在管道文件中的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
執行完之後的結果:
管道持久化存儲示例:
爬取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
基於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, }
執行爬蟲程式,並去資料庫中查看數據
基於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中的數據
redis已經存在數據了,因為編碼問題所以不顯示中文.