2016-05-22 3 views
0

Я, вероятно, могу решить это сам, если бы у меня было время для расследования. Я пробовал разные вещи, но я не могу заставить его работать! Я занимаюсь своим мастером в области маркетинга, и мы ожидаем, что сможем на самом Python закодировать набор данных (json) в организованный текстовый файл, который можно использовать для дальнейшего анализа.Разбор JSON с использованием try и except

У нас есть набор данных с большим количеством недостающих значений. То, что я хочу разобрать, это: artist, mbid (music brainz artist id), данные о событиях, название места, город.

Это (часть) сценарий я написал для этого:

for event in setlists: 
    eventdate = event.get(u'@eventDate') 
    venuename = event.get(u'venue').get(u'@name') 
    mbid = event.get(u'artist').get(u'@mbid') 
    artistname = event.get(u'artist').get(u'@name') 
    city = event.get(u'venue').get(u'city').get(u'@name') 

    f = open(parse_file, 'a') 
    f.write(artistname+'\t'+mbid+'\t'+eventdate+'\t'+venuename+'\t'+city+'\n') 
    f.close() 

Этот скрипт работает как шарм, за исключением того, что он выходит из записей, для которых имеются пропущенные значения, например, нет города.

Я хочу, чтобы он сообщал об этом в текстовую строку и печатал «отсутствует» для информации, которая отсутствует.

Я не могу заставить его работать, и я не знаю, с чего начать. Я пытался что-то вроде этого:

f = open(parse_file, 'a') 
try: f.write(artistname) except: continue try: f.write(mbid) except:  continue... 
f.close() 

Каждая строка в анализируемом файле хотел бы, как это:

artistname mbid EVENTDATE venuename расположение

Я пытаюсь поставить все на разных линиях, но тогда проблема был выход по вертикали, а не по горизонтали для каждого события.

+2

Не могли бы вы добавить образец файла JSON и желаемый результат? –

+0

Вы должны поместить свою попытку: кроме: операторов в разных строках. Это не имеет никакого отношения к форматированию вывода файла. – Keozon

+0

Я пробовал делать, что Кеозон. Попытайтесь получить .... кроме, продолжайте, а затем еще одну попытку и за исключением. А потом, когда я е = открытое (parse_file, 'а') \t \t f.write (EVENTDATE + '\ т' + город + '\ п') \t \t f.close() он все равно будет выводиться только комбинации, где оба переменные присутствуют ... – Luti

ответ

0

Попробуйте - за исключением первого блока, где вы извлекаете данные в своем примере city = event.get(u'venue').get(u'city').get(u'@name') - get не работает, так что происходит с обработкой.

UPDATE:

Согласно представленным данным, - это то, что работает. Обратите внимание, что данные не являются файлом JSON. Это набор строк, где каждый из них является JSON-файлом ... Вот почему я сделал readlines, а затем обработал каждый из них. Это можно сделать более питоническим, более эффективным с точки зрения памяти, но я хотел показать, как решить проблему. Надеюсь, что это помогает:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import json 
from StringIO import StringIO 

with open('sample.json.txt') as data_file: 
    content = data_file.readlines() 

f = open('out_ok.txt', 'a') 
errors = open('out_errors.txt', 'a') 

try: 
    for ctx in content: 
     line = StringIO(ctx) 
     try: 
      json_data = json.load(line) 
     except UnicodeDecodeError: 
      errors.write('unicode: ' + ctx) 
      continue 
     event = json_data.get('setlists').get('setlist') 
     try: 
      eventdate = event.get(u'@eventDate') 
      venuename = event.get(u'venue').get(u'@name') 
      mbid = event.get(u'artist').get(u'@mbid') 
      artistname = event.get(u'artist').get(u'@name') 
      city = event.get(u'venue').get(u'city').get(u'@name') 
      f.write(artistname+'\t'+mbid+'\t'+eventdate+'\t'+venuename+'\t'+city+'\n') 
     except AttributeError: 
      errors.write('json: ' + json.dumps(event)) 
finally: 
    f.close() 
    errors.close() 
+0

Прежде всего, спасибо, что ответили! Если я запустил это, я не получаю никакого вывода, он дает ошибку на каждой строке! – Luti

+0

Ну, так я не могу вам помочь. Я имею в виду - предоставить примеры событий, которые я могу проверить, и обновить свой ответ ... –

+0

благодарит за ответ! – Luti

1

Так что это определенно не право способ сделать это, но так как вы в спешке ...

for event in setlists: 
    eventdate = event.get(u'@eventDate', 'missing') 
    venuename = event.get(u'venue', {u'@name': 'missing'}).get(u'@name', 'missing') 
    mbid = event.get(u'artist', {u'@mbid': 'missing'}).get(u'@mbid', 'missing') 
    artistname = event.get(u'artist', {u'@name': 'missing'}).get(u'@name', 'missing') 
    city = event.get(u'venue').get(u'city', {u'@name': 'missing'}).get(u'@name', 'missing') 

<etc> 

Идея заключается в том, чтобы поставить по умолчанию аргументы в .get, так что ваши вложенные методы .get имеют что-то .get: P

+0

'mbid = event.get (u'artist ', {u' @ mbid ':' missing '}). Get (u' @ mbid ',' missing ')' можно упростить до просто mbid = event.get (u'artist ', {}). get (u' @ mbid ',' missing ') '- то есть, первый вызов, который нужно получить, просто должен вернуть пустой dict, так как вы даете аргумент по умолчанию во втором вызове получить. Сделайте это повсюду, и он немного очистит код. И я не знаю, почему вы говорите, что это неправильный способ сделать это, я думаю, что он удовлетворяет требованиям просто отлично, с минимальной суетой. – PaulMcG

+0

Это немного почищает, спасибо. И вы также правы в этом, чтобы удовлетворить требования просто отлично, я думаю, что часть меня склоняется к предварительной обработке данных немного больше, так что .gets не нужны, но я, вероятно, просто чересчур суетливый: P –