Firefox-родное сообщение: как отправить JSON и сохранить CSV - PullRequest
0 голосов
/ 02 июля 2018

В настоящее время я работаю над дополнением Firefox, которое должно взаимодействовать с локальной программой на языке Python. Таким образом, существует файл JS с именем Background.js, который отправляет сообщение json в собственное приложение.

Предполагается, что нативное приложение python получает сообщение и сохраняет его в локальном файле. Пока все хорошо, проблемы возникают, когда я пытаюсь сохранить входящие пакеты json в непрерывном файле csv.

файл JS отправляет сообщения вроде этого:

      {"messageId": countGlobalId(), "url": e.target.href,
      "innerHTML": e.target.innerHTML,
      "outerHTML": e.target.outerHTML,
      "tagName": e.target.tagName});
  }

Базовая функциональность предоставляется. В файле Python следующая функция получает сообщение и возвращает jsonobject?!:

def getMessage():
    rawLength = sys.stdin.buffer.read(4)
    if len(rawLength) == 0:
        sys.exit(0)
    messageLength = struct.unpack('@I', rawLength)[0]
    message = sys.stdin.buffer.read(messageLength)#.decode('utf-8')
    jsonMessage= json.loads(message)
    return jsonMessage

Здесь возникает проблема; следующий цикл должен сохранить входящие данные в указанный CSV-файл:

while True:
    receivedMessage = getMessage()
    if receivedMessage:
        messageString=json.dumps(receivedMessage)
        with open("ts.csv",'wb') as csvfile:
            writer= csv.DictWriter(csvfile,
                fieldnames=('messageId', 'url', 'innerHTML',
                'outerHTML', 'tagName'), extrasection='ignore') 
            #writer.writerows(receivedMessage)
            writer.writerows(messageString)
            # just trying alot of combinations above

SendMessage ...

Я знаю, что моя проблема заключается в последнем цикле while, но не могу найти где. Я попробовал более простую версию, просто чтобы проверить механику записи файлов, и она отлично работала:

    while True:
        receivedMessage = getMessage()
        if receivedMessage:
            file=open("ts.csv,'a')
            file.write(json.dumps(receivedMessage))
            file.close()
sendmessage...

Кроме того, мой единственный способ отладки этого проекта - запуск фрагментов в отдельных тестовых файлах Pyrthon, поскольку нативное приложение вызывается надстройкой, а консоли нет.

Итак, как, черт возьми, я мог заставить мои данные json аккуратно вписаться в CSV-диктат?

Это цель сделать что-то вроде этого:

import csv
toCSV = [{'name':'bob','age':25,'weight':200},
         {'name':'jim','age':31,'weight':180}]
keys = toCSV[0].keys()
with open('people.csv', 'wb') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(toCSV)

Как мне преобразовать этот список словарей в CSV-файл?

Это прекрасно работает в закрытой среде.

Но когда я настраиваю свой код на:

while True:
    receivedMessage = getMessage()
    if receivedMessage:
        keys = receivedMessage[0].keys()
        with open('testfile.csv', 'wb') as output_file:
            dict_writer = csv.DictWriter(output_file, keys)
            dict_writer.writeheader()
            dict_writer.writerows(receivedMessage)

скрипт останавливается.

EDIT :::::::::::: Основная проблема заключалась в том, что мое исходное сообщение иногда содержало пустые записи. Чтобы решить эту проблему, я добавил несколько строк в создание JS:

if (e.target.href)
  {urlVar= e.target.href;}
  else {urlVar= "empty";}
if (e.target.innerHTML)
  {innerHTMLVar= e.target.innerHTML;}
  else {innerHTMLVar= "empty";}
if (e.target.outerHTML)
  {outerHTMLVar= e.target.outerHTML;}
  else {outerHTMLVar= "empty";}
if (e.target.tagName)
  {tagNameVar= e.target.tagName;}
  else {tagNameVar= "empty";}

Это, похоже, помогло, и теперь нативное приложение Python может использовать данные следующим образом:

....
jsonMessage= json.loads(message)
...
    with open('testfile.csv', 'a', newline='') as csvfile:
        fieldnames = ['messageId', 'url', 'innerHTML', 'outerHTML', 'tagName']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writerow(jsonMessage)
...