【爬虫】5.Scrapy数据封装,处理,导出等等


创建一个Scrapy项目会在项目目录下自动创建多个.py文件,他们各自承担不同的作用。
在这里插入图片描述

数据封装

对抓取的零散数据如何维护,在之间的例子中我们使用了python的dict。

            yield {
                 # xpath 语法 @ATTR 为选中为名ATTR的属性节点
                 'name': book.xpath('h3/a/@title').get(),
                 'price': book.css('p.price_color::text').get(),
             }

但是字典存在一定的缺陷,所以Scrapy提供了两个类允许用户自定义数据类,并封装起来。
● Item基类:自定义数据类(如BookItem)的基类。
● Field类:用来描述自定义数据类包含哪些字段(如name、price等)

可在item.py文件中实现自定义数据

from scrapy import Item, Field

class BookItem(Item):
    name = Field()
    price = Field()

在spider中导入自定义数据类,并修改代码

from ..items import	BookItem

class BooksSpider(scrapy.Spider):
	...
    def parse(self, response):
        for books in response.css('article.product_pod'):
            book = BookItem()
            book['name'] = books.xpath('h3/a/@title').extract_first()
            book['price'] = books.css('p.price_color::text').extract_first()
            yield book
    ...

Item支持字典接口,因此BookItem在使用上和Python字典类似,可按上述方式创建BookItem对象 book['name'] = books.xpath('h3/a/@title').extract()

数据处理

在Scrapy中,Item Pipeline是处理数据的组件,一个Item Pipeline就是一个包含特定接口的类,通常只负责一种功能的数据处理,在一个项目中可以同时启用多个Item Pipeline,它们按指定次序级联起来,形成一条数据处理流水线。 以下是Item Pipeline的几种典型应用:
● 清洗数据。
● 验证数据的有效性。
● 过滤掉重复的数据。
● 将数据存入数据库。

实现

重写pipelines.py文件,将价格单位重英镑改为人民币

class PriceConverterPipeline(object):
    exchange_rate=8.5309
    def	process_item(self,item,spider):
        #	提取item的price字段(如£53.74)
        #	去掉前面英镑符号£,转换为float类型,乘以汇率
        price=float(item['price'] [1:])*self.exchange_rate
        #	保留2位小数,赋值回item的price字段
        item['price']='¥%.2f'%price
        return item

可以看出,process_item方法是Item Pipeline的核心,对该方法还需再做两点补充说明:

  • 如果process_item在处理某项item时返回了一项数据(Item或字典),返回的数据会递送给下一级Item Pipeline(如果有)继续处理。
  • 如果process_item在处理某项item时抛出(raise)一个DropItem 异常(scrapy.exceptions.DropItem),该项item便会被抛弃,不再递送给后面的Item Pipeline继续处理,也不会导出到文件。通常, 我们在检测到无效数据或想要过滤数据时,抛出DropItem异常。

除了必须实现的process_item方法外,还有3个比较常用的方法,可根据需求选择实现:

  • open_spider(self, spider) Spider打开时(处理数据前)回调该方法,通常该方法 用于在开始处理数据之前完成某些初始化工作,如连接数据库。
  • close_spider(self, spider) Spider关闭时(处理数据后)回调该方法,通常该方法 用于在处理完所有数据之后完成某些清理工作,如关闭数据库。
  • from_crawler(cls, crawler) 创建Item Pipeline对象时回调该类方法。通常,在该方法 中通过crawler.settings读取配置,根据配置创建Item Pipeline对象。 在后面的例子中,我们展示了以上方法的应用场景。

配置

因为Item Pipeline是可选的组件,所以想要启用Item Pipeline,需要在配置文件settings.py中进行配置:

ITEM_PIPELINES = {'example.pipelines.PriceConverterPipeline': 300, }

ITEM_PIPELINES是一个字典,我们把想要启用的Item Pipeline添加到这个字典中,其中每一项的键是每一个Item Pipeline类的导入路径,值是一个0~1000的数字,同时启用多个Item Pipeline时,Scrapy根据这些数值决定各Item Pipeline处理数据的先后次序,数值小的在前。

more example

过滤重复数据

# 过滤重复数据,以name为依据
class DuplicatesPipeline(object):
    def	__init__(self):
        self.book_set = set()
        def	process_item(self, item, spider):
            name = item['name']
            if name	in self.book_set:
                raise DropItem("Duplicate book found: %s" %item)
            self.book_set.add(name)
            return item

数据存储到mongodb

from scrapy.item import Item
import pymongo
class MongoDBPipeline(object):
    DB_URI = 'mongodb://localhost:27017/'
    DB_NAME	= 'scrapy_data'
    def open_spider(self,	spider):
        self.client	= pymongo.MongoClient(self.DB_URI)
        self.db = self.client[self.DB_NAME]

    def	close_spider(self,	spider):
        self.client.close()

    def	process_item(self,	item,	spider):
        collection=self.db[spider.name]
        post=dict(item)if isinstance(item,	Item)else item
        collection.insert_one(post)
        return item
ITEM_PIPELINES={								'example.pipelines.PriceConverterPipeline':300,								'example.pipelines.DuplicatesPipeline':350,
'example.pipelines.MongoDBPipeline':400,
}

使用LinkExtractor提取链接

获取连接有两种方式

  • Selecor
  • LinkExtractor

Selector

因为链接也是页面中的数据,所以可以使用与提取数据相同的方法进行提取,在提取少量(几个)链接或提取规则比较简单时,使用Selector就足够了。

LinkExtractor

from scrapy.linkextractors import LinkExtractor
class BooksSpider(scrapy.Spider):
	...	
	def parse(self,	response):
	...	
	le = LinkExtractor(restrict_css='ul.pager li.next')
	links = le.extract_links(response)	
	if links:	
		next_url = links[0].url
		yield scrapy.Request(next_url,callback=self.parse)

描述规则

参数描述
allow接收一个正则表达式或一个正则表达式列表,提取绝对url与正则表达式匹配的链接,如果该参数为空(默认),就提取全部链接。
deny接收一个正则表达式或一个正则表达式列表,与allow相反,排除绝对url与正则表达式匹配的链接。
allow_domains接收一个域名或一个域名列表,提取到指定域的链接。
deny_domains接收一个域名或一个域名列表,与allow_domains相反, 排除到指定域的链接。
restrict_xpaths接收一个XPath表达式或一个XPath表达式列表,提取 XPath表达式选中区域下的链接。
restrict_css接收一个CSS选择器或一个CSS选择器列表,提取CSS选择器选中区域下的链接。
tags接收一个标签(字符串)或一个标签列表,提取指定标签内的链接,默认为[‘a’, ‘area’]。
attrs接收一个属性(字符串)或一个属性列表,提取指定属性内的链接,默认为[‘href’]。
process_value接收一个形如func(value)的回调函数。如果传递了该参数,LinkExtractor将调用该回调函数对提取的每一个链接(如a的href)进行处理,回调函数正常情况下应返回一个字符串(处理结果),想要抛弃所处理的链接时, 返回None。

数据导出

数据导出有两种方式

  • 命令行
  • 配置文件

运行scrapy crawl命令通过-t指定到处类型,-o导出路径

scrapy crawl books -t csv -o books1.data
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值