우아한테크코스 팀 프로젝트를 진행하면서 공공데이터를 활용하여 그 과정을 기록해보고자 한다.
우리가 사용한 데이터는 농촌 진흥청의 실내정원 식물 데이터 이고, 응답 데이터 형식은 xml
이다.
데이터 파싱을 위해 python
, beautifulsoup
를 사용하였다.
그리고 환경설정 및 pandas 사용이 편리하기 때문에 구글에서 제공해주는 코랩(jupyter notebook
)을 사용하였다.
데이터 사용 신청
을 진행하고, 승인 후에 작업을 진행한다.
구글 코랩을 사용한다면 아래와 같은 설정을 통해, 개인 드라이브에 접근하여 파일을 저장하고 불러올 수 있다.
만약 구글 코랩을 사용하지 않는다면 이 설정은 하지 않아도 무방하다.
from google.colab import drive
drive.mount('/content/drive')
사용할 모듈을 import 해준다.
아래 모듈들은 각각 요청, 데이터 파싱, 전처리 및 CSV 파일 저장을 위해 imort 하였다.
import requests
from bs4 import BeautifulSoup
import pandas as pd
공통적으로 사용되는 값들도 미리 설정하였다.
각각의 변수에 들어갈 값은 아래와 같다.
api_key = "발급 받은 api key" # 1
request_key_format = "apiKey=" + api_key # 2
base_url = "http://api.nongsaro.go.kr/service/garden/" # 3
아래 값들을 미리 설정해줍니다.
(1)요청 url에 사용될 keyword
(2)한 페이지에 몇 개의 데이터를 받아올지에 대한 값
garden_list_keyword = "gardenList" # 1
rows = "217" # 2
요청을 편하게 보낼 수 있도록 함수를 작성하였습니다.
인자 값으로는 요청 url에 사용될 keyword와 한 페이지에 받을 데이터 수가 들어가게 됩니다.
find_all
). def request_with_num_of_rows(keyword, rows):
request_url = base_url + keyword + "?" + request_key_format + "&numOfRows=" + rows
response = requests.get(request_url)
response_xml = BeautifulSoup(response.text,'lxml-xml')
return response_xml.find_all("item") # 1
위에서 설정한 변수들과 메서드를 조합하여 요청을 보냅니다.
garden_list_items = request_with_num_of_rows(garden_list_keyword, rows)
데이터 파싱을 위한 함수를 만들어줬습니다.
아래 함수를 하나씩 확인해보겠습니다.
item에서 cntntsNo
태그에 대한 값을 찾고 text를 추출합니다. 이 때 item은 item 태그를 가진 데이터 입니다. cntnts_no
는 원하는 임의의 변수로 지정하시면 됩니다.
return 값은 코드에 나타낸 것과 같이 딕셔너리 이고, 키:밸류 형태를 가지고 있습니다.
이 때 딕셔너리의 키 값은 원하는 컬럼명을 적고, 그 뒤에는 1번에서 정한 임의의 변수를 적어줍니다. value 값으로 cntnts_no
로 작성하시면 됩니다.
하지만 결과 값이 (데이터,)
형태를 가지는 튜플 타입이기 때문에 저는 cntnts_no[0]
으로 작성하였습니다.
rtn_file_url[0].split('|')[0]
부분을 보면 split을 사용했습니다. |
를 기준으로 여러 데이터가 들어있는 스트링이기 때문에 사용한 것입니다. 저는 여러 데이터 중 첫번째 데이터만 사용할 것이므로 0번째 인덱스의 값만 사용하도록 작성하였습니다.
def parse_garden_list(item):
cntnts_no = item.find("cntntsNo").get_text(), # 1
cntnts_sj = item.find("cntntsSj").get_text(),
rtn_file_url = item.find("rtnFileUrl").get_text(),
return { # 2
"컨텐츠번호": cntnts_no[0], # 3
"식물명": cntnts_sj[0],
"저장파일url": rtn_file_url[0].split('|')[0] # 4
}
item 태그를 가진 값들의 목록들을 인자로 받고, for문을 돌면서 item을 하나씩 파싱한 후 데이터 프레임화를 할 수 있는 함수를 만들었습니다.
def make_dataframe_for_garden_list(items):
row = []
for item in items:
row.append(parse_garden_list(item))
return pd.DataFrame(row)
(1) 앞서 만든 함수를 적용해서 파싱 및 데이터프레임화를 완료합니다.
(2) 변수를 셀 마지막에 찍으면 print(garden_list_df)
를 한 것과 같은 결과를 볼 수 있습니다.
garden_list_df = make_dataframe_for_garden_list(garden_list_items) # 1
garden_list_df #2
원하는 경로와 파일이름을 적고 저장하면 파일 생성을 할 수 있습니다.
garden_list_df.to_csv("경로/원하는 이름.csv")
많은 도움이 되었습니다, 감사합니다.