Я столкнулся с любопытной проблемой при анализе объектов json в больших текстовых файлах, и решение, которое я нашел, на самом деле не имеет особого смысла. Я работал со следующим скриптом. Он копирует файлы bz2, распаковывает их, затем анализирует каждую строку как объект json.Python - пропущенные символы Readline
import os, sys, json
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# USER INPUT
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
args = sys.argv
extractDir = outputDir = ""
if (len(args) >= 2):
extractDir = args[1]
else:
extractDir = raw_input('Directory to extract from: ')
if (len(args) >= 3):
outputDir = args[2]
else:
outputDir = raw_input('Directory to output to: ')
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# RETRIEVE FILE
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
tweetModel = [u'id', u'text', u'lang', u'created_at', u'retweeted', u'retweet_count', u'in_reply_to_user_id', u'coordinates', u'place', u'hashtags', u'in_reply_to_status_id']
filenames = next(os.walk(extractDir))[2]
for file in filenames:
if file[-4:] != ".bz2":
continue
os.system("cp " + extractDir + '/' + file + ' ' + outputDir)
os.system("bunzip2 " + outputDir + '/' + file)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# PARSE DATA
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
input = open (outputDir + '/' + file[:-4], 'r')
output = open (outputDir + '/p_' + file[:-4], 'w+')
for line in input.readlines():
try:
tweet = json.loads(line)
for field in enumerate(tweetModel):
if tweet.has_key(field[1]) and tweet[field[1]] != None:
if field[0] != 0:
output.write('\t')
fieldData = tweet[field[1]]
if not isinstance(fieldData, unicode):
fieldData = unicode(str(fieldData), "utf-8")
output.write(fieldData.encode('utf8'))
else:
output.write('\t')
except ValueError as e:
print ("Parse Error: " + str(e))
print line
line = input.readline()
quit()
continue
print "Success! " + str(len(line))
input.flush()
output.write('\n')
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# REMOVE OLD FILE
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
os.system("rm " + outputDir + '/' + file[:-4])
При чтении в определенных строках в цикле for line in input.readlines():
, линии будут иногда быть усечены в непоследовательных местах. Поскольку символ новой строки также усекался, он продолжал читать, пока не найдет символ новой строки в конце следующего объекта json. Результатом был неполный json-объект, за которым следует полный json-объект, все рассмотренные одной строкой анализатором. Я не мог найти причину этой проблемы, но я обнаружил, что изменение петли на
filedata = input.read()
for line in filedata.splitlines():
работал. Кто-нибудь знает, что здесь происходит?
Попробуйте просто выполнить итерацию непосредственно в файле: 'для строки ввода: ...' – poke
Не могу сказать, почему она не работает, но может предложить предложение. 'readlines()' is noteccesary, вы можете перебирать файл-объект непосредственно таким образом: 'для строки на входе:' – SiHa
Да, я пробовал это. Это привело к тому же вопросу. –