개요
다음과 같은 JSON 문자열을 JSON 객체로 변환하려고 하던 중 아래와 같은 에러가 발생했다.
import json
payload = """{
'http://example.org/about': {
'http://purl.org/dc/terms/title': [
{'type': 'literal', 'value': "Anna's Homepage"}
]
}
}"""
print(json.loads(payload))
원인을 알아보고 해결 방법을 적어둔다.
원인
문자열이 JSON 형식에 맞지 않아 파싱 에러가 발생한 것이다. https://www.rfc-editor.org/rfc/rfc7159#section-7에 의하면 JSON에서는 문자열이 큰 따옴표로 시작하고 끝나야 한다.
즉, 아래 문자열은 JSON 형식이 아니다.
{
'http://example.org/about': {
'http://purl.org/dc/terms/title': [
{'type': 'literal', 'value': "Anna's Homepage"}
]
}
}
아래 문자열이 JSON 형식이다.
{
"http://example.org/about": {
"http://purl.org/dc/terms/title": [
{"type": "literal", "value": "Anna's Homepage"}
]
}
}
해결 방법
일단 문자열의 따옴표를 JSON 형식에 맞게 수정하는 방법이 있을 수 있다.
또는 문자열을 Python 객체인 dictionary로 변환한 뒤 json.dumps 함수를 사용하는 방법이 있다.
import json
import ast
def str_to_json(input_str):
# 문자열을 dictionary로 변환
dict_input = ast.literal_eval(input_str)
# json 로드
return json.dumps(dict_input)
str_to_json 함수 내에 print문을 추가하여 dict_input의 값과 데이터형을 출력해 보면,
위와 같이 dictionary 형의 객체가 된 것을 확인할 수 있다.
이 데이터를 json 로드한 결과는 다음과 같다.
정상적인 JSON 형식의 데이터가 된 모습을 확인할 수 있다.
+ 다만 literal_eval은 300자 이상의 문자열에 대해 사용하는 경우 메모리 에러가 발생할 수 있다고 하니 주의하여야 한다.
참고 문서