Skip to content

hyesungoh/Cultural_Heritage_Administration_API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cultural_Heritage_Administration_API

문화재청 Open API 사용


#### LikeLion 8th hackathon 출품 예정작 '공아역'에 사용
  • 사용자의 검색에 맞는 문화재 이미지 및 정보 출력을 위함

20.09.06 기준

import requests
search_name = '숭례문'
url_list = 'http://www.cha.go.kr/cha/SearchKindOpenapiList.do?pageUnit=30&ccbaMnm1=' + search_name

html = requests.get(url_list)
  • requests를 사용하여 api 호출
  • 문화재청 api는 별도의 key가 존재하지 않음
  • ccbaMnm1은 문화재의 이름, 예를 들기 위하여 '숭례문'으로 설정 이름을 기준으로 문화재 검색을 위함
  • pageUnit은 한 페이지에 보여줄 문화재의 수, 30으로 설정 검색 결과에 해당하는 모든 문화재를 보여주기 위해 api를 여러번 호출하는 방법 대신 적당히 보여준 후 사용자의 자세한 검색 유도
sp_html = html.text.split('<sn>')
  • 호출한 값(html 형식)을 순번 태그인 <sn>을 기준으로 split
# 딕셔너리들이 들어갈 리스트
searched_list = []
for heritage in sp_html:
    # split된 값들을 bs를 사용하여 parsing
    temp_html = BeautifulSoup(heritage, 'html.parser')

    # 태그들이 없는 html 선언부분등을 예외처리
    try:
        # 빈 딕셔너리 생성
        temp_dict = {}
        # 각 정보에 해당하는 key와 value 넣어줌
        temp_dict['문화재명1'] = temp_html.ccbamnm1.text
        temp_dict['문화재명2'] = temp_html.ccbamnm2.text
        temp_dict['위치_도'] = temp_html.ccbactcdnm.text
        temp_dict['위치_시'] = temp_html.ccsiname.text
        temp_dict['종목코드'] = temp_html.ccbakdcd.text
        temp_dict['시도코드'] = temp_html.ccbactcd.text
        temp_dict['지정번호'] = temp_html.ccbaasno.text
        searched_list.append(temp_dict)
    except:
        pass
  • split된 html 내용을 기준으로 for문 수행
  • 각 값들을 BeautifulSoup을 사용하여 parsing
  • 필요한 내용의 이름과 값을 각 딕셔너리의 key와 value로 저장한 후 searched_list에 추가
  • sp_html에 head 태그와 같이 필요한 태그들이 존재하지 않은 요소들이 있기 때문에 try, except를 사용하여 예외처리

20.09.08 기준

for heritage in sp_html:
    temp_html = BeautifulSoup(heritage, 'html.parser')
    try:
        temp_dict = {}
        temp_dict['문화재명1'] = temp_html.ccbamnm1.text
        temp_dict['문화재명2'] = temp_html.ccbamnm2.text
        temp_dict['위치_도'] = temp_html.ccbactcdnm.text
        temp_dict['위치_시'] = temp_html.ccsiname.text

        temp_kbcd = temp_html.ccbakdcd.text
        temp_dict['종목코드'] = temp_kbcd

        temp_ctcd = temp_html.ccbactcd.text
        temp_dict['시도코드'] = temp_ctcd

        temp_anno = temp_html.ccbaasno.text
        temp_dict['지정번호'] = temp_anno

        temp_require = 'ccbaKdcd=' + temp_kbcd + '&ccbaCtcd=' + temp_ctcd + '&ccbaAsno=' + temp_anno

        # img_url = 'http://www.cha.go.kr/cha/SearchImageOpenapi.do?' + temp_require
        # img = requests.get(img_url)
        # sp_img = img.text.split('<sn>')
        # parsed_img = BeautifulSoup(sp_img[1], 'html.parser')
        # temp_dict['이미지'] = parsed_img.imageurl.text

        detail_url = 'http://www.cha.go.kr/cha/SearchKindOpenapiDt.do?' + temp_require

        detail = requests.get(detail_url)
        parsed_detail = BeautifulSoup(detail.text, 'html.parser')
        temp_dict['이미지'] = parsed_detail.imageurl.text
        temp_dict['내용'] = parsed_detail.content.text


        searched_list.append(temp_dict)
    except:
        pass
  • 문화재 이미지 검색 api와 문화재 상세정보 api를 둘 다 호출하지 않고 문화재 상세정보에 있는 대표 이미지를 사용
  • 상세정보 검색에 필요한 종목, 지정, 시도 코드를 변수로 지정 > url 요첨에 필요한 문자열을 변수로 지정
  • 문화재 검색과 같이 requests, BeautifulSoup를 사용
  • 문화재 리스트에 존재하는 문화재 마다 api를 호출하여 시간이 오래걸리는 이슈가 있음, 어떻게 해결해야 될까?

20.09.14 기준

  • 문화재청 API에 총 15935개의 정보가 있음 > 검색마다 API를 호출하는 건 상당히 비효율 적이라고 생각 > 개발 환경에서 model에 저장 후 필요한 정보를 불러오는 방법을 사용해야겠음 > 장고 프로젝트에서 모델을 만들어야 함 > 기존 슬라이싱 및 파싱한 것을 토대로 모델에 저장 > 15000여개의 데이터를 모델에 저장하면서 경과치를 볼 수 있을까?

20.09.15 기준

  • 장고 모델에 15000여개의 데이터를 저장 > 검색은 filter을 이용하여 구현할 예정

20.09.18 기준

  • 모델 저장 페이지에서 api를 호출하여 저장하는 방법 대신, 로컬에서 api에서 필요한 정보를 뺀 파일을 만들어 그것을 이용하여 저장하는 방법을 사용할 예정

20.09.19 기준

f = open("heritage.txt", 'a')

... 중략

for i in searched_list:
    for key, value in i.items():
        txt_data = key + ':' + value
        f.write(txt_data)
f.close()
  • 파일 입출력을 이용하여 key와 value를 :로 나누어 저장, 이제 15000여개의 모델을 저장하면서 진행상황을 어떻게 볼지 고민중

20.09.20 기준

url_list = 'http://www.cha.go.kr/cha/SearchKindOpenapiList.do?pageUnit=15944'
  • api에서 가져올 요소의 수를 api에 존재하는 모든 문화재 수인 19544로 설정
progress = 1
for heritage in sp_html:
    temp_html = BeautifulSoup(heritage, 'html.parser')
    try:
        temp_dict = {}
        temp_dict['문화재명1'] = temp_html.ccbamnm1.text
        ... 중략
        print('현재 진행상황 : ', progress)
        progress += 1
    except:
        pass
  • 반복문에 출력문을 넣어 경과정도를 확인할 수 있게 함
f.write(str(searched_list))
  • 딕셔너리 자료형들로 이루어진 리스트를 문자열화하여 파일에 입력

20.09.21 기준

progress = 1
for heritage in sp_html:
    temp_html = BeautifulSoup(heritage, 'html.parser')
    try:
        temp_dict = {}
        ... 중략
        print(str(temp_dict))
        f.write(str(temp_dict)+'\n')
        print('현재 진행상황 : ', progress)
        progress += 1
    except:
        pass
  • 반복문에 출력문과 더불어 파일.write를 줄바꿈과 같이 저장하는 방식으로 바꿈

20.09.22 기준

  • heritage.txt 파일을 장고 프로젝트에 넣기 전 확인 용으로 txt_reader.py를 생성
heritage_txt = open("heritage.txt", 'r')
  • 읽기 전용으로 파일 open
for _ in range(5):
    line = heritage_txt.readline()
    heritage_list.append(eval(line))
# [{문화재1 정보}, {문화재2 정보}, ...]
  • eval을 이용하여 문자열로 저장된 딕셔너리들을 새로운 리스트에 추가
heritage_list = []
i = 0
while True:
    line = heritage_txt.readline()
    if not line: break
    heritage_list.append(eval(line))

    i += 1
    if i % 100 == 0: print(i, "/ 19544")

print(heritage_list[0]['문화재명1'])
# 서울 숭례문
print('총 문화재 수 : ', len(heritage_list))
# 총 문화재 수 :  15944
heritage_txt.close()
  • 무한 반복문을 이용하여 파일 끝까지 readline하여 append

20.09.25 기준

  • Django 프로젝트에서 기존에 저장한 .txt 파일을 이용하여 Model Heritage에 저장
if len(Heritage.objects.all()) > 10:
      pass
  • Heritage Model의 갯수가 10개 이하일 때만 txt 파일을 읽고 모델에 저장되도록 함
else:
      module_dir = os.path.dirname(__file__)
      file_path = os.path.join(module_dir, '/Users/ohyeseong/Documents/django/dino_history/dino_history/heritage/heritage.txt')
      heritage_txt = open(file_path, 'r')

      while True:
          line = heritage_txt.readline()
          if not line: break

          this_heritage = eval(line)

          temp_heritage = Heritage()
          temp_heritage.name = this_heritage['문화재명1']
          temp_heritage.location = this_heritage['위치_도'] + this_heritage['위치_시']
          temp_heritage.dynasty = this_heritage['시대']
          temp_heritage.img_url = this_heritage['이미지']
          temp_heritage.content = this_heritage['내용']
          temp_heritage.longitude = this_heritage['경도']
          temp_heritage.latitude = this_heritage['위도']
          temp_heritage.save()

  return render(request, 'heritage/save_test.html')
  • 기존 txt_reader.py와 다르게 매 line마다 Heritage model을 생성 및 딕셔너리를 이용하여 저장

About

문화재청 open api 사용 with Python

Topics

Resources

Stars

Watchers

Forks

Languages