Elasticsearch存储scrapy item失败(Unable to serialize)与scrapy Item的序列化serializer问题

我在将scrapy爬取来的内容存入Elasticsearch时发现这么一个问题:

Unable to serialize

研究了半天,发现其原有的serialize方法非常低效,不管是使用serializer还是重写serialize_field函数

def serialize_price(value):
    return '$ %s' % str(value)

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field(serializer=serialize_price)
 def serialize_field(self, field, name, value):
        if field == 'price':
            return '$ %s' % str(value)
        return super(Product, self).serialize_field(field, name, value)

其实Item最主要的部分就是一个dict结构,有些时候它使用起来与普通的dict没有区别,但很多时候它无法代替dict的使用,因为dict是基本数据结构,而Item本质是一个class。

其实不用那么费劲去研究序列化,scrapy的这个设计个人觉得有点脱裤子放屁的感觉。一条语句搞定:

_xwDoc = {k: item[k] for k in item}

这样是不是把那个复杂的序列化解决了?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Scrapy中爬取的数据存储Elasticsearch中,可以使用Scrapy-Redis和Elasticsearch-py插件。 第一步,安装Scrapy-Redis插件和Elasticsearch-py插件: ``` pip install scrapy-redis pip install elasticsearch ``` 第二步,在Scrapy项目的settings.py文件中添加如下配置: ``` # 使用Scrapy-Redis调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 使用Redis的去重组件 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 允许暂停,redis请求记录不丢失 SCHEDULER_PERSIST = True # Redis连接信息 REDIS_HOST = 'localhost' REDIS_PORT = 6379 # Elasticsearch连接信息 ELASTICSEARCH_SERVERS = ['http://localhost:9200/'] ELASTICSEARCH_INDEX = 'my_index' ELASTICSEARCH_TYPE = 'my_type' ``` 第三步,在Scrapy项目的pipelines.py文件中添加如下代码: ``` from elasticsearch import Elasticsearch from scrapy.utils.project import get_project_settings from scrapy_redis.pipelines import RedisPipeline class ElasticsearchPipeline(object): def __init__(self): settings = get_project_settings() self.es = Elasticsearch(settings['ELASTICSEARCH_SERVERS']) self.index = settings['ELASTICSEARCH_INDEX'] self.type = settings['ELASTICSEARCH_TYPE'] def process_item(self, item, spider): self.es.index(index=self.index, doc_type=self.type, body=dict(item)) return item class MyPipeline(RedisPipeline): def __init__(self, settings): RedisPipeline.__init__(self) self.elasticsearch = ElasticsearchPipeline() def process_item(self, item, spider): self.elasticsearch.process_item(item, spider) return RedisPipeline.process_item(self, item, spider) ``` 最后,在Scrapy项目的spiders中添加如下代码: ``` from scrapy_redis.spiders import RedisSpider class MySpider(RedisSpider): name = 'my_spider' redis_key = 'my_spider:start_urls' def parse(self, response): # 解析页面 pass ``` 这样,Scrapy就会将爬取的数据存储Elasticsearch中了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值