Разбор GTFS в реальном времени без протобуфа с питоном - PullRequest
2 голосов
/ 14 июня 2019

Я пытаюсь проанализировать GTFS данные в реальном времени trip_update, которые имеют формат простого текстового файла, а не в формате pb (protobuf).

(вот адрес канала)

https://extranet.trainose.gr/epivatikos/transit/trip_updates

Тем не менее, единственные примеры, которые я нахожу, касаются pb-файлов.

from google.transit import gtfs_realtime_pb2
....
response = requests.get(url, allow_redirects=True)
feed.ParseFromString(response.content)
for entity in feed.entity:

Так, как я мог разобрать канал, который не является pb? Благодарю.

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Оказывается, что есть способ обработать боль текстовой подачей примерно так:

   response = requests.get(url, allow_redirects=True)
    ...
    try:
        from google.protobuf import text_format
        text_format.Parse(response.content.decode('UTF-8'), feed, allow_unknown_extension=True)
        print("Parse with text format successfully.")
        printResults(feed)
    except text_format.ParseError as e:
            raise IOError("Cannot parse text %s." % (str(e)))

на самом деле вот весь мой сценарий

from google.transit import gtfs_realtime_pb2
import os
import requests


def main():
    feed = gtfs_realtime_pb2.FeedMessage()
    url = ('https://feed.utl.com/feed')
    get_feed(feed, url)

def printResults(feed):
    from datetime import datetime
    ts = int(str(feed.header.timestamp))
    print("Last update: " + datetime.fromtimestamp(ts).strftime('%d-%m-%Y %H:%M:%S'))
    for entity in feed.entity:
        print (str(entity.trip_update.trip.trip_id)+';')
        with open('output.txt', mode='w') as f:
            for entity in feed.entity:
                if entity.HasField('trip_update'):
                        f.write(str(entity.trip_update.trip.trip_id)+';')
def get_feed(feed, url):
    proxies = {'http': '127.0.0.1:5555','https': '127.0.0.1:5555'}
    response = requests.get(url, allow_redirects=True,proxies=proxies)
    try:
        feed.ParseFromString(response.content)
        printResults(feed)
    except :
        print("Oops!  That was no valid data. Try again...\n\n" + response.content)
        try:
            from google.protobuf import text_format
            text_format.Parse(response.content.decode('UTF-8'), feed, allow_unknown_extension=True)
            print("Parse with text format successfully.")
            printResults(feed)
        except text_format.ParseError as e:
            raise IOError("Cannot parse file %s." % (str(e)))
if __name__ == "__main__":
    main()
1 голос
/ 15 июня 2019

Человекочитаемый текст не является стандартным форматом для отправки и получения протобуф-сообщений.(Если вам нужен только простой текст, вы должны использовать стандартный текстовый формат, такой как JSON.) В принципе, это только для целей отладки.Таким образом, в библиотеке Python Protobuf нет методов для анализа текстовых сообщений.Правильное решение здесь - найти фактическую конечную точку protobuf, возможно, связавшись с владельцем домена.( РЕДАКТИРОВАТЬ : по-видимому, на самом деле существует метод Parse для текстовых сообщений в библиотеке Python - см. Исходный код здесь .)

.библиотека C ++ Protobuf, по-видимому, содержит методы для непосредственного анализа текстового формата, поэтому, если у вас нет возможности получить доступ к настоящему протобуфу, это может быть опция резервного копирования: https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.text_format.

Нет строгих правилнасколько я знаю, гарантии согласованности текстового формата между версиями, но тот факт, что он представлен в библиотеке, предполагает, что он, вероятно, довольно стабилен на практике.Это обсуждение создает такое же впечатление (поскольку существуют внутренние инструменты Google, которые анализируют текстовый формат): https://github.com/protocolbuffers/protobuf/issues/1297#issuecomment-390825524.

...