Python-如何将Feedparser对象传递给芹菜任务?

时间:2015-02-12 08:54:31

标签: python celery feedparser jsonserializer

我使用feedparser模块来解析RSS提要。我需要将feedparser对象传递给芹菜任务。

尝试传递对象时,收到错误time.struct_time(tm_year=2015, tm_mon=2, tm_mday=12, tm_hour=8, tm_min=19, tm_sec=11, tm_wday=3, tm_yday=43, tm_isdst=0) is not JSON serializable

如何将feedparser对象传递给芹菜任务?

这是我的代码: -

rss_content = feedparser.parse(rss_link)
content_entries = rss_content['entries']
for content in content_entries:
    parse_link.apply_async(args=[content, link, json_id, news_category], queue= news_source) #celery task

我该怎么做?

1 个答案:

答案 0 :(得分:1)

您需要创建自定义编码器和解码器,基本上将您的time.time_struct对象转换为可序列化的(dict),然后按照docs中的说明在kombu序列化程序注册表中注册它们,为了让芹菜在其任务中使用新的序列化器。

import json
import time
import types
import datetime

class FeedContentEncoder(json.JSONEncoder):   
    def default(self, obj):
        if isinstance(obj, time_struct):
            epoch = int(time.mktime(time_struct))
            return {'__type__': '__time__', 'time': epoch}
        else:
            return json.FeedContentEncoder.default(self, obj)

def decode_feed_content(obj):
    if isinstance(obj, types.DictionaryType) and '__type__' in obj:
        if obj['__type__'] == '__time__':
            return datetime.datetime.fromtimestamp(obj['time']).timetuple()
    return obj

您需要通过将新序列化注册到序列化程序注册表来通知kombu。

from kombu.serialization import register

def feed_content_json_dumps(obj):
    return json.dumps(obj, cls=FeedContentEncoder)

def feed_content_json_loads(obj):
    return json.loads(obj, object_hook=decode_feed_content)

register('feedcontentjson', 
         feed_content_json_dumps, 
         feed_content_json_loads, 
         content_type='application/x-feedcontent-json', 
         content_encoding='utf-8') 

最后,您应该告诉芹菜使用新的序列化程序来序列化任务,就像celery docs;您应该使用serializer参数调用您的任务。

parse_link.apply_async(args=[content, link, json_id, news_category], queue= news_source, serializer='feedcontentjson')

希望这有帮助。