✅ DB에 데이터 저장 후 추출 vs API로 호출해오기 : 둘 중 더 효율적인 것은?
✅ DB에 데이터 저장하는 방법 고안 & 초기 세팅
👉 json 값에서 원하는 정보만 추출해서 DB에 담기
DB에 코드를 담을 때 가장 어려운 것은
얽히고 섥혀있는 json
구조를 파악하고
예외사항을 try except
구문으로 막아줘야 한다는 점이었다.
그래서 코드가 많이 길어졌다...
import json
import os
import re
from dotenv import load_dotenv
# dotenv에서 key값을 참조하기 때문에 dotenv를 load 해와야 함
dotenv_path = os.path.join(os.path.dirname(__file__), ".env")
load_dotenv(dotenv_path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
import django
django.setup()
from crawled_data.models import KrDictQuiz, KrDictQuizExample, KrDictQuizExplain
# 파일 바뀔 때 마다 경로 바꿔서 설정
with open(
"F:/nbc/final_project/전체 내려받기_한국어기초사전_JSON_20230612/1079331_51959.json",
"r",
encoding="utf-8",
) as file:
data = json.load(file)
word_list = data["LexicalResource"]["Lexicon"]["LexicalEntry"]
pattern = r"[^\w\s]"
def kr_dict():
word_data = []
for i in range(len(word_list)):
# word 단어
my_word = ""
lemma = word_list[i]["Lemma"]
if isinstance(lemma, list):
for item in lemma:
if item["feat"]["att"] == "writtenForm":
my_word = item["feat"]["val"]
else:
my_word = lemma["feat"]["val"]
# 특수문자가 포함된 단어는 제외
if re.findall(pattern, my_word):
continue
# explain과 example
sense = word_list[i]["Sense"]
if isinstance(sense, list):
feats = [sense[j]["feat"] for j in range(len(sense))]
sense_examples = []
for k in range(len(sense)):
try:
sense_examples.append(sense[k]["SenseExample"])
except KeyError:
sense_examples.append(None)
else:
feats = sense["feat"]
try:
sense_examples = [sense["SenseExample"]]
except KeyError:
sense_examples = None
my_explain = []
if isinstance(feats, list):
for feat in feats:
if isinstance(feat, list):
for item in feat:
if item["att"] == "definition":
my_explain.append(item["val"])
else:
my_explain.append(feat["val"])
else:
if feats["att"] == "definition":
my_explain.append(feats["val"])
# difficulty 난이도
# 0(없음), 1(초급), 2(중급), 3(고급)
my_difficulty = 0
try:
feat = word_list[i]["feat"]
dif = {"없음": 0, "초급": 1, "중급": 2, "고급": 3}
if isinstance(feat, list):
for item in feat:
if item["att"] == "vocabularyLevel":
my_difficulty = dif[item["val"]]
else:
if feat.get("att") == "vocabularyLevel":
my_difficulty = dif[feat["val"]]
except KeyError:
pass
# example 단어 예시 - type, contents
my_all_examples = []
if sense_examples is not None:
for examples in sense_examples:
if examples is not None:
if isinstance(examples, list):
for example in examples:
skip_example = False
for ex in example["feat"]:
# "대화"인 경우에는 현재의 example을 건너뜀
if ex["val"] == "대화":
skip_example = True
break
if ex["att"] == "type":
my_type = ex["val"]
elif ex["att"] == "example":
my_content = ex["val"]
if not skip_example:
my_all_examples.append({my_type: my_content})
else:
for ex in examples["feat"]:
if ex["att"] == "type":
my_type = ex["val"]
elif ex["att"] == "example":
my_content = ex["val"]
my_all_examples.append({my_type: my_content})
complete_word = {
"word": my_word,
"explain": my_explain,
"difficulty": my_difficulty,
"example": my_all_examples,
}
word_data.append(complete_word)
return word_data
if __name__ == "__main__":
dict_words = kr_dict()
for dict_word in dict_words:
my_word = KrDictQuiz(word=dict_word["word"], difficulty=dict_word["difficulty"])
my_word.save()
for explain in dict_word["explain"]:
my_explain = KrDictQuizExplain(dict_word=my_word, content=explain)
my_explain.save()
for example in dict_word["example"]:
if "구" in example:
my_type = 0
my_content = example["구"]
if "문장" in example:
my_type = 1
my_content = example["문장"]
my_example = KrDictQuizExample(
dict_word=my_word, word_type=my_type, content=my_content
)
my_example.save()
print("데이터 베이스에 저장 완료!!")
정규표현식으로 특수문자가 들어가는 단어를 제외하고 크롤링 할 수 있게 했다.
그리고 대화형식을 제외하고 예시를 수집했다.
나머지는 대부분 예외 사항 처리.. 위치 찾기.. 오류 처리 이런식이라서 저번과 크게 다를 것 없다.
그리고 파일을 직접 실행했을때만 모델에 저장할 수 있게 if __name__ == "__main__"
구문을 넣어 처리해주었다.