2026. 7. 7. 00:17ㆍAI/웹 크롤링
1. 서울 열린 데이터 광장 (Seoul Open Data Plaza)
서울 열린 데이터 광장은 서울시에서 운영하는 공공데이터 개방 플랫폼이다.
시민, 연구자, 기업 등이 서울시에서 생성한 다양한 공공데이터를
자유롭게 활용할 수 있도록 제공한다.
이를 통해 데이터 기반의 창의적인 아이디어와 혁신을 촉진하고
시민들의 정보 접근성을 높이고 공공서비스를 개선하는데 기여하고 있다.
2. 서울시 공공자전거 실시간 대여정보
https://data.seoul.go.kr/dataList/OA-15493/A/1/datasetView.do
열린데이터광장 메인
데이터분류,데이터검색,데이터활용
data.seoul.go.kr
현재 OPENAPI 형태로 제공되고 있다.
우리는 JSON 형태로 받을 것이다.
1) JSON(JavaScript Object Notation)
데이터를 저장하거나 프로그램끼리 데이터를 주고받기 위해 사용하는 데이터 형식이다.
웹 개발, AI, 공공데이터 API, 앱 개발 등 거의 모든 분야에서 사용된다.
# 1. 파이썬의 JSON 모듈
import json
# 2. 파이썬 객체 -> JSON 문자열 변환
json.dumps()
# 3. JSON 문자열 -> 파이썬 객체 변환
json.loads()
# 4. JSON 데이터 접근 -> 딕셔너리처럼 접근
print(data['name'])
2) API (Application Programming Interface)
API는 서로 다른 프로그램이나 서비스가 데이터 주고받도록 연결해주는 통로 역할의 기술이다.
공공데이터에서 제공하는 API는 다양한 데이터를 개발자가 프로그램에서
직접 사용할 수 있도록 제공하는 서비스이다.
예를 들어, 날씨 API 사용 시 웹사이트나 앱에서 실시간 날씨 정보를 가져와 화면에 표시할 수 있다.
대부분의 공공데이터 API는 요청을 보내면 JSON 또는 XML 형태로
데이터를 응답해주며 이를 활용해 다양한 서비스들을 개발할 수 있다.
3) 호출 방법

이 주의사항에서 보면, 최대 1000건 별로 나누어서 호출해야 한다.
URL에는 인증키가 필요한데, GUI 방식의 인증키 발급을 통해 발급하여 URL에 추가하면 된다.
요청 인자들은 다음과 같다.

import requests
import folium
import json
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
import os
from dotenv import load_dotenv
load_dotenv()
def fetch_bike_data():
key = os.getenv('KEY')
base_url = f'http://openapi.seoul.go.kr:8088/{key}/json/bikeList/'
start = 1
end = 1000
step = 1000
data_frames = []
while True:
url = f"{base_url}{start}/{end}/"
response = requests.get(url)
print(response.status_code)
if response.status_code != 200:
print(f"Status Code: {response.status_code}")
break
json_data = response.json()
try:
rent_bike_status = json_data["rentBikeStatus"]
result_code = rent_bike_status["RESULT"]["CODE"]
except KeyError:
print("JSON 오류")
break
if result_code == 'INFO-200':
print("데이터 없음")
break
elif result_code == 'INFO-000':
print(f"시작: {start} 끝: {end}.")
try:
bike_data = rent_bike_status["row"]
if bike_data:
df = pd.DataFrame(bike_data)
data_frames.append(df)
except KeyError:
print("데이터를 찾을 수 없음")
else:
print(f"result code : {result_code}")
break
start += step
end += step
if data_frames:
final_df = pd.concat(data_frames, ignore_index=True)
return final_df
else:
return pd.DataFrame()
bike_data_df = fetch_bike_data()
bike_data_df

4) 데이터 컬럼 의미
bike_data_df.info()

- rackTotCnt : 거치대 갯수
- parkingBikeTotCnt : 자전거 주차 총 건수
- shared : 거치율
- stationLatitude : 위도
- stationLongitude : 경도
- stationId : 대여소ID
- stationName : 대여소 이름
5) 위/ 경도를 가지고 지도에 시각화
bike_data_df['stationLongitude'] = bike_data_df['stationLongitude'].astype(float)
bike_data_df['stationLatitude'] = bike_data_df['stationLatitude'].astype(float)
bike_map = folium.Map(location=[bike_data_df['stationLatitude'].mean(), bike_data_df['stationLongitude'].mean()], zoom_start=12)
for index, data in bike_data_df.iterrows():
popup_str = '{} 자전거주차총건수: {}대'.format(data['stationName'], data['parkingBikeTotCnt'])
popup = folium.Popup(popup_str, max_width = 600)
folium.Marker(location=[data['stationLatitude'], data['stationLongitude']], popup=popup).add_to(bike_map)
bike_map

'AI > 웹 크롤링' 카테고리의 다른 글
| 웹 크롤링 - 셀레니움 (5) (0) | 2026.07.06 |
|---|---|
| 웹 크롤링 - 크롤링의 활용 (4) (0) | 2026.07.02 |
| 웹 크롤링 - 크롤링과 HTML (3) (0) | 2026.07.02 |
| 웹 크롤링 - Git과 Github (2) (0) | 2026.07.02 |
| 웹 크롤링 - 인터넷과 웹 서비스 (1) (0) | 2026.07.02 |