Шаблонный разбор ленты - PullRequest
3 голосов
/ 23 июня 2009

Требования: У меня есть проект на Python, который анализирует потоки данных из нескольких источников в различных форматах (Atom, допустимый XML, недопустимый XML, CSV, почти мусор и т. Д.) И вставляет полученные данные в базу данных. Улов - это информация, необходимая для разбора каждого из каналов, также должна храниться в базе данных.

Текущее решение: Мое предыдущее решение состояло в том, чтобы хранить небольшие скрипты Python, которые оцениваются на необработанных данных, и возвращать объект данных для проанализированных данных. Я бы очень хотел уйти от этого метода, поскольку он, очевидно, открывает неприятную дыру в безопасности.

Идеальное решение: То, что я ищу, - это то, что я бы описал как синтаксический анализатор каналов для Python, управляемый шаблоном, чтобы я мог написать файл шаблона для каждого из форматов канала, и этот файл шаблона будет использоваться для понимания различных данных. форматы.

У меня был ограниченный успех в поиске чего-то подобного в прошлом, и я надеялся, что у кого-то может быть хорошее предложение.

Спасибо всем!

1 Ответ

1 голос
/ 23 июня 2009

Вместо eval скриптов, возможно, вам стоит подумать о том, чтобы сделать из них пакет? Синтаксический анализ CSV - это одно - формат простой и регулярный, синтаксический анализ XML требует совершенно другого подхода. Учитывая, что вы не хотите писать каждый парсер с нуля, почему бы просто не написать кучу маленьких модулей, каждый из которых имеет идентичный API, и использовать их? Я считаю, что использование самого Python (а не некоторого шаблонного DSL) идеально подходит для такого рода вещей.

Например, такой подход я видел в одном небольшом скрипте для извлечения торрентов Я использую:

Основная программа:

...
def import_plugin(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

...
feed_parser = import_plugin('parsers.%s' % feed['format'])
data = feed_parser(...)
...

parsers/csv.py:

#!/usr/bin/python
from __future__ import absolute_import

import urllib2
import csv

def parse_feed(...):
    ...

Если вам не особенно нравятся динамически загружаемые модули, вы можете рассмотреть, например, написание одного модуля с несколькими классами синтаксического анализа (вероятно, производными от некоторого базового класса "абстрактный парсер").

class BaseParser(object):
    ...

class CSVParser(BaseParser):
    ...
register_feed_parser(CSVParser, ['text/plain', 'text/csv'])
...

parsers = get_registered_feed_parsers(feed['mime_type'])
data = None
for parser in parsers:
    try:
        data = parser(feed['data'])
        if data is not None: break
    except ParsingError:
        pass
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...