마음대로 안되는게 너무 많아서 하루종일 붙잡고 있던 과제...🥲
이 길이 내 길이 아닌가 했지만.....결국엔 해결했다. 다 좋은 경험이겠지~
1) 기본 라이브러리 불러오기
import pandas as pd
import requests
- pandas: 데이터를 DataFrame 형태로 관리하고 분석하는 데 사용
- requests: HTTP 요청을 보내 API로부터 데이터를 가져오는 데 사용
2) API 요청
- colab 환경에서 작업을 수행했는데 여기서부터 오류....🤢
- 사실 이전 데이터도 오류가 나서 다른 데이터로 바꿨기 때문에 슬슬 힘들기 시작했다
- 여기서 오류가 왜 나...? 라는 마음에 멘붕, 다른 방법도 시도해 봤지만 여기서 다른 방법이 필요할 리가..
- API에 대한 지식이 있는 개발자에게 조언을 들은 바로는 API에서 colab이 차단당한 것 같다고!
- 그래서 vs code로 작업 환경을 바꿔 보았고 오류 없이 잘 실행되었다 🥺 (컴맹은 이걸로 하루를 날려먹어....)
💡 오류가 날 상황이 아닌 것 같은데 오류가 난다면? 다른 작업환경에서 실행해보자‼️
url = 'http://api.gwangju.go.kr/xml/stationInfo'
params = {'serviceKey' : '서비스키' }
response = requests.get(url, params=params)
- url: API 엔드포인트 URL. 광주 API의 stationInfo 정보를 가져오는 URL
- params: API 호출 시 필요한 인증 키를 포함한 파라미터
- serviceKey: API 제공자로부터 발급받은 서비스 키
- params 표현 방식은 아래처럼 두 가지로 가능
params = {'serviceKey' : '서비스키'}
params = {('serviceKey', '서비스키')}
- requests.get():
- API에 GET 요청을 보내 데이터를 받아옴
- 반환된 response 객체는 API의 응답 데이터를 포함
3) XML 데이터 파싱
import xml.etree.ElementTree as ET
root = ET.fromstring(response.text)
- response.text:
- API 응답 데이터를 XML 형식의 텍스트로 반환
- ET.fromstring():
- XML 데이터를 트리(tree) 구조로 변환하여 root 객체로 저장
- 이제 XML 데이터를 태그 기반으로 순회하거나 특정 데이터를 추출할 수 있게 됨
4) 데이터 저장용 딕셔너리 초기화
row_dict = {
'BUSSTOP_ID': [], 'BUSSTOP_NAME': [], 'NAME_E': [],
'LONGITUDE': [], 'LATITUDE': [], 'ARS_ID': [], 'NEXT_BUSSTOP': []
}
- row_dict:
- 데이터를 저장하기 위한 딕셔너리
- 각 키는 XML 데이터에서 추출할 태그 이름과 동일하며, 값은 해당 태그의 데이터를 저장할 빈 리스트로 초기화됨
5) XML 데이터 순회 및 데이터 추출
for station in root.findall('.//STATION_LIST/STATION'):
for child in station:
if child.tag in row_dict: # 딕셔너리에 있는 태그만 처리
row_dict[child.tag].append(child.text)
- root.findall('.//STATION_LIST/STATION'):
- XML에서 <STATION_LIST> 태그 아래의 모든 <STATION> 태그를 찾음
- 각 <STATION> 태그는 하나의 버스 정류소 정보를 나타냄
- for child in station:
- 각 <STATION> 태그의 자식 태그들(<BUSSTOP_ID>, <BUSSTOP_NAME>, 등)을 순회
- if child.tag in row_dict:
- 자식 태그 이름이 row_dict에 정의된 키와 일치하는 경우에만 데이터를 처리
- 해당 태그의 텍스트 값을 딕셔너리의 해당 리스트에 추가
6) 누락된 데이터 처리
- 누락된 데이터를 처리하지 않아서 또 한번 오류..!😵💫
for key in row_dict:
if len(row_dict[key]) < len(row_dict['BUSSTOP_ID']): # 가장 긴 리스트에 맞춰 길이 보정
row_dict[key].append(None)
- 왜 누락된 데이터를 처리하는가?
- XML 데이터에서 일부 태그가 누락된 경우, 리스트의 길이가 달라질 수 있음
- Pandas DataFrame은 각 열(리스트)의 길이가 동일해야 하므로, 누락된 데이터에 대해 None 값을 추가하여 리스트의 길이를 맞춰야함
- 어떻게 길이를 맞추는가?
- row_dict['BUSSTOP_ID']의 길이를 기준으로 각 리스트 비교
- 특정 태그의 리스트가 짧으면 None 값 추가
- 누락된 데이터가 없는 리스트라면 다른 리스트도 가능
7) DataFrame 생성 및 결과 확인
df = pd.DataFrame(row_dict)
df.head() # print로 출력하면 표 형태로 나오지 않음
- Pandas DataFrame:
- row_dict 딕셔너리를 Pandas DataFrame으로 변환
- 각 키(BUSSTOP_ID, BUSSTOP_NAME, 등)는 DataFrame의 열 이름이 되고, 각 리스트는 열의 데이터로 변환
- df.head():
- DataFrame의 상위 5개 데이터를 출력하여 데이터가 올바르게 처리되었는지 확인
8) 최종 코드
# 기본 라이브러리 불러오기
import pandas as pd
import requests
# API 요청
url = 'http://api.gwangju.go.kr/xml/stationInfo'
params ={'serviceKey' : '서비스키' }
response = requests.get(url, params=params)
# XML 데이터 파싱
import xml.etree.ElementTree as ET
root = ET.fromstring(response.text)
# 데이터 저장용 딕셔너리 초기화
row_dict = {
'BUSSTOP_ID': [], 'BUSSTOP_NAME': [], 'NAME_E': [],
'LONGITUDE': [], 'LATITUDE': [], 'ARS_ID': [], 'NEXT_BUSSTOP': []
}
# XML 데이터 순회 및 데이터 추출
for station in root.findall('.//STATION_LIST/STATION'):
for child in station:
if child.tag in row_dict: # 딕셔너리에 있는 태그만 처리
row_dict[child.tag].append(child.text)
# 누락된 데이터 처리
for key in row_dict:
if len(row_dict[key]) < len(row_dict['BUSSTOP_ID']): # 가장 긴 리스트에 맞춰 길이 보정
row_dict[key].append(None)
# DataFrame 생성
df = pd.DataFrame(row_dict)
# 결과 확인
df.head()
9) 실행 결과
'Python' 카테고리의 다른 글
Python 코드카타: 행렬의 덧셈 (0) | 2025.02.06 |
---|---|
Python 챌린지반 과제: 코드 저장하고 빅쿼리에 데이터 올리기_시행착오.. (0) | 2025.01.22 |
Python 코드카타: 부족한 금액 계산하기 | 문자열 다루기 기본 (0) | 2025.01.13 |
Python 코드카타: 약수의 개수와 덧셈 | 문자열 내림차순으로 배치하기 (0) | 2025.01.08 |
Python 코드카타: 수박 | 내적 (0) | 2025.01.07 |