공공 데이터 XML 크롤링을 통해 Django HTML에 띄워보기

Public API XML Crawling Parsing with Django

요새 코딩을 모르는 일반인들도 파이썬을 접하면서 크롤링을 해볼만큼 크롤링에 대한 이슈는 꽤 보편적으로 전파된 듯하다.

이전에 지인과 함께 식사를 하면서 얼핏 들었던 이야기인데, 한 방송국의 신입 기자가 매 주 들어오는 타 미디어 보도 자료를 정리해오는 업무를 해야하는데, 함께 들어온 동기들은 보도 자료가 업로드된 미디어 업체 페이지를 수작업으로 접속해 기사를 스크랩 했는데, 이 영리한 신입 기자는 크롤링으로 검색어를 맞춰 필요한 기사만 뽑아 빠르게 스크래핑 해서 보고서를 올렸다는 소문이다. 이후 동기들보다 진급이 훨씬 빨랐다는 루머 아닌 루머.

프로그래밍은 본인의 상황에 잘 맞게 사용한다면 우리의 일상 생활을 자동화 시켜 효율성을 높이는 최고의 도구가 될 수 있다.

그렇다면 크롤링의 보편적인 방식에는 어떤 것이 있을까?

일반적으로 크롤링을 할 때 2가지 방식을 사용하는 것이 구글에서 가장 많이 검색되는 듯하다.

  1. Beautiful Soup를 사용해서 검색엔진 결과값 크롤링하기

Beautifulsoup라는 라이브러리를 사용해서 N사, G사 등의 검색엔진에 검색어 설정을 하게 되면 키워드와 관련한 결과값들을 원하는 만큼 서칭할 수 있다. 다만, 이 주제는 오늘 다룰 이야기는 아니기 때문에 추후에 작성하도록 하겠다.

2. xmltodict 라이브러리를 사용해서 공공데이터 API 파싱

오늘 다룰 주제이자 django 등 파이썬을 사용한 프레임워크에서 어떻게 이 정보들을 필요한 부분만 쏙! 빼올 수 있는지 기술할 것이다.

먼저 공공 데이터 API를 받아오기

공공 데이터들은 https://www.data.go.kr/ 해당 URL로 넘어가면 본인들이 원하는 공공 데이터를 찾아볼 수 있다. 이 글에서는 미세먼지 정보에 대한 API를 받아올 것이다.

아, 물론 공공데이터 API를 신청하고 발급받는 과정은 구글에 너무나도 잘 설명된 블로그들이 즐비하고, Django 기본 세팅에 대한 설명을 풀어놓은 블로그도 정말 많다. 때문에 API 발급 절차와 pip install django 등 세부적인 설명은 이들 블로그들을 찾아보시길!

필자는 start project 명칭을 rendering이라 명칭했고, 내부의 App은 airapi라고 명칭했다.

이와 관련하여 airapi 앱 내에 crawling.py라는 파이썬 파일 하나를 형성하자.

Django 폴더 구조

crawling.py를 만들었다면 이제 내부에 코드를 작성해보자.

당연하지만, API 키 값은 가리는 것이 원칙이다.

공공데이터를 크롤링하는 소스코드는 이게 전부다. 정말 쉽지 않나!? 물론 이 내부에는 이 크롤링을 도와주는 몇 개의 라이브러리가 함께 작동하긴 하지만 고작 requests, xmltodict 2가지만 사용하고 있다. (time은 시행착오를 겪는 과정에서 더 이상 사용하지 않는 라이브러리다.)

먼저 Django를 사용한다면 분명 가상환경에서 돌리고 있을테니, 가상환경을 켜 놓은 상태에서 2개의 라이브러리를 설치하자.

pip install requests

pip install xmltodict

라이브러리를 설치하면 requests와 xmltodict를 드디어 공공데이터 파싱에 사용할 수 있게 된다!

각각의 용도는 코드를 해설하면서 이야기하겠다.


import requests

import xmltodict

import time

def dustParsing():

# public api settings

sido = “인천” # 서울, 부산, 대구, 인천, 광주, 대전, 울산, 경기, 강원, 충북, 충남, 전북, 전남, 경북, 경남, 제주, 세종 / 당신이 미세먼지 농도를 알고 싶은 지역을 입력하자

key = “당신이 발급받은 키값”

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

url = “http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnMesureSidoLIst?sidoName=" + \

sido + “&searchCondition=Hour&PageNo=1&numOfRows=200&ServiceKey=” + key

pm10 = {} # pm10이라는 딕셔너리는 crawling.py에서 필요없다. 시행착오를 겪는 과정에서 지우지 못한 부분이다.

result = ‘’ # 마찬가지로 필요없으니 복붙할 때 지우시길!

req = requests.get(url).content #여기서 requests가 필요하다.

# the role of xmltodict : It changes xml type into dictionary.

xmlObject = xmltodict.parse(req)

allData = xmlObject[‘response’][‘body’][‘items’][‘item’]

# allData = xmlObject[‘response’][‘body’][‘items’][‘item’][0][‘dataTime’] 는 후반부에 설명하겠다.

return allData

# print(allData)


코드 구조는 이렇게 짜여 있는데 위에서부터 설명하자면

  • requests는 우리가 특정 웹 페이지에 요청을 보내는 것이다. 지금 글을 예로 들면 공공데이터 포털에 “우리가 미세먼지에 관한 정보가 필요한데, 내가 필요한 정보를 보내달라”고 하는 것이다.
  • 다만, 해당 url 변수에 sido, key라는 변수가 지정되어 있다. 공공데이터 포털에서 발급받은 키 값과 지역을 입력해야 본인이 발급받은 고유 페이지로 접속해 확인할 수 있다.
  • 이렇게 발급받은 url 페이지는 여러 요청을 처리할 수 있는데 대표적으로 JSON & XML을 많이 사용한다. 오늘은 XML을 사용한다고 했으니 XML 페이지를 통해 크롤링을 진행한다.
  • xmlObject = xmltodict.parse(req) 이 구문을 보면 xmldodict라이브러리를 사해서 요청한 페이지의 url을 쪼개(parse) 객체를 형성하겠다는 것이다.
  • allData = xmlObject[‘response’][‘body’][‘items’][‘item’] 이제 여기서부터 중요한데 밑의 텍스트 이미지를 보라.
해당 텍스트의 구조를 보라!
  • <response><header><body><items><item></item></items></body></header></response> 이라고 위계가 짜여 있다. 내가 받고 싶었던 정보는 각 아이템 내의 지역이름(cityName)과 미세먼지&초미세먼지 정보(pm10Value&pm25Value)이므로 이 정보만 따로 처리해야한다.

그런데 allData = xmlObject[‘response’][‘body’][‘items’][‘item’] 이 값을 콘솔창에 띄워보면,

이 배열에서 내가 필요한 정보만 쏙! 빼야한다.

‘인천’에 해당되는 지역의 모든 미세먼지 정보가 출력되었다. 이럼 안되지!


이걸 이제 정돈되서 html에서 띄우려면 한 번더 정보를 가공해야된다. 이 작업은 이제 views.py로 넘어가야한다!

airapi/views.py

메인페이지(home.html)에 미세먼지 정보를 띄울텐데, 그러려면 pm10(미세먼지) / pm25(초미세먼지)를 지역별로 처리할 딕셔너리를 초기화해야한다.

그러러면 crawling.py에서 만든 dustParsing이라는 함수를 불러와서 객체로 만들어야한다. 객체화하면 해당 처리된 정보들을 air라는 변수로 받을 수 있고, for문을 사용해 pm10 = {‘도시 이름’: ‘미세먼지 값’}, pm25 = {‘도시 이름’: ‘초미세먼지 값’} 형태로 받을 수 있다. 그리고 각 객체들을 home.html로 렌더링을 해준다.


이제 home.html로 넘어가보자.

django html 문법은 일반 html과는 약간 다르다. 그래서 중괄호 내에 {% %} 문법 등이 사용된다.

우리가 사용한 것은 딕셔너리기 때문에 for문을 사용할 때 딕셔너리.items를 이용하면 key:value pair 값을 받아올 수 있다. key 값이 해당 지역이 맞다면, 지역에 맞는 value를 출력할 수 있다. html을 브라우저에 띄워보면

정상적으로 미세먼지 지수와 지역이 출력된다.

이렇게 HTML에 띄울 수 있다. 아직은 크롤링 정보를 DB에 저장해 사용할 정도는 아니라서 DB를 가볍게 하고 싶었고, Django 문법 사용시 권고 사항 중 하나는 views.py를 가볍게 하는 것이다. 그래서 crawling.py를 따로 작성한 것이었고, 사용 용도에 따라 모듈화를 했다.

공공데이터를 크롤링한 정보도 django에서 충분히 쉽게 다룰 수 있는 주제이니 틈틈이 다른 정보도 크롤링해서 사용해볼 수 있는 토이 프로젝트를 해봐야겠다.

— Ryan Kim

 

[출처] https://medium.com/@equus3144/%EA%B3%B5%EA%B3%B5-%EB%8D%B0%EC%9D%B4%ED%84%B0-xml-%ED%81%AC%EB%A1%A4%EB%A7%81%EC%9D%84-%ED%86%B5%ED%95%B4-django-html%EC%97%90-%EB%9D%84%EC%9B%8C%EB%B3%B4%EA%B8%B0-db96d395d4dd

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED