Scrapy持久化
方式一(了解):
此方式针对小型项目,利用其可以轻松将输出抓取到文件中
1 parser解析函数,return 列表,列表套字典 2 命令行持久化到文件中:scrapy crawl chouti -o aa.json (支持:('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle')
方式二:piplines的方式(重点)
1、在items.py中创建模型类
- Item 是保存爬取数据的容器,它的使用方法和字典类似。不过相比字典, Item 多了额外的保护机制,可以避免拼写错误或者定义字段错误。
- Item 是保存爬取数据的容器,它的使用方法和字典类似。不过,相比字典, Item 多了额外的保护机制,可以避免拼写错误或者定义字段错误。
- 创建Item 需要继承scrapy.Item 类,并且定义类型为scrapy.Field 的字段。观察目标网站,我们可以获取到到内容有id、title、url、img_url
import scrapy # 写一个模型类,用来存储解析出来的数据 class CrawlChoutiItem(scrapy.Item): id=scrapy.Field() title = scrapy.Field() url = scrapy.Field() img_url = scrapy.Field()
2、在爬虫中chouti.py文件中导入,把解析的数据放到item对象中(记得要用中括号)
上文定义了Item ,接下来就要使用它了。Item 可以理解为一个字典,不过在声明的时候需要实例化。然后依次用刚才解析的结果赋值Item 的每一个字段, 最后将Item 返回即可。
def parse(self, response): # 解析,请求回来,自动执行parser,在这个方法中做解析 div_list = response.xpath('//div[contains(@class,"link-item")]') for div in div_list: title = div.xpath('.//a[contains(@class,"link-title")]/text()').extract_first() url = div.xpath('.//a[contains(@class,"link-title")]/@href').extract_first() img_url = div.xpath('.//*[contains(@class,"matching")]/@src').extract_first() id = div.xpath('.//a[contains(@class,"link-title")]/@data-id').extract_first() print(''' 新闻标题:%s 新闻连接:%s 新闻图片:%s ''' % (title, url, img_url)) item=CrawlChoutiItem() # 实例除一个item对象 # #这种方式不行,必须使用中括号方式 # # item.title=title 报错 item['id']=id #填写配置的参数 item['title']=title item['url']=url item['img_url']=img_url # # 注意用yield # return item yield item
3、在配置文件中配置管道
ITEM_PIPELINES = { # 数字表示优先级(数字越小,优先级越大) 'crawl_chouti.pipelines.CrawlChoutiPipeline': 400, 'crawl_chouti.pipelines.CrawlChoutiRedisPipeline': 301, }
4、在piplines.py中写持久化类
Item Pipeline 为项目管道。当Item 生成后,它会自动被送到Item Pipeline 进行处理
from redis import Redis class CrawlChoutiPipeline(object): def process_item(self, item, spider): pass class CrawlRedisPipeline(object): # 存redis数据库 def open_spider(self,spider): print('redis开始') self.conn = Redis(db=6,password='Admin123') # process_item()方法有两个参数。一个参数是item,每次Spider生成的Item都会作为参数传递过来。另一个参数是spider,就是Spider的实例 # process_item可以返回数据的字典或item对象 def process_item(self,item,spider): import json s = json.dumps({'title':item['title'],'usrl':item['url'], 'img_url':item['img_url']}) self.conn.hset('chouti_article',item['id'],s) print('redis') return item # 写return表示按优先级继续往下走 def close_spider(self,spider): print('redis结束') self.conn.close()