[아이티윌 빅데이터 52기] LAB 13 | 파이썬 파이널 과제 | OpenAPI 연동 실습 (선생님 버전)
모든 과제에 대한 저작권은 아이티윌 이광호 강사님께 있습니다

활용할 데이터 셋
서울교통공사_역주소 및 전화번호> 데이터셋> 공공데이터 | 서울열린데이터광장
<풀이 순서>
STEP1. 패키지 참조
STEP2. CSV 파일 읽어오기
STEP 3. Open API 데이터 요청 스펙 확인
STEP4. 위경도를 조회하는 함수 정의
STEP.5-1 위경도 변환하기 | 동기 방식
STEP.5-2 위경도 변환하기 | 비동기 방식
STEP.6 변환 결과 저장하기
STEP1. 패키지 참조
import requests
from pandas import DataFrame
from concurrent import futures
STEP2. CSV 파일 읽어오기
#서울 열린 데이터 광장 - 서울 교통공사 역주소 및 전화번호 최근 데이터셋을 다운받아 r 읽기 모드로 데이터를 가져온다
with open("서울교통공사_역주소 및 전화번호_20250318.csv","r",encoding='euc-kr') as f:
#데이터 세트 객체를 한 행씩 읽는 readlines() 메서드를 활용하고, 해당 결과를 csv_list 에 담는다
csv_list=f.readlines()
print(csv_list[:5])
STEP 3. Open API 데이터 요청 스펙 확인
OPEN API 를 연결할 때의 작업 항목들 살펴보면,
OPEN API 요청 정보를 확인하고, SESSION 객체로 URL 에 접속하여 데이터를 가져오는 것.
#요청 url
url = "https://api.vworld.kr/req/address?"
key = "생략"
#요청 파라미터 (명세서 확인)
params = {
"service": "address",
"request": "getcoord",
"crs": "epsg:4326",
"address": "판교로 242",
"format": "json",
"type": "road",
"key": key
}
#웹에 데이터 요청하기
with requests.Session() as session:
#세션 객체에 웹 브라우저 정보 (UserAgent) 주입 (웹서버가 파이썬 프로그램을 정상적인 웹 브라우저로 여기도록)
session.headers.update({"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
})
r=session.get(url,params=params) #get 메서드로 접근하고, 파라미터 값 쿼리 스트링 형태로 전달
print(r.url)
if r.status_code !=200:
msg ="[%d Error] %s 에러가 발생함" % (r.status_code,r.reason)
raise Exception(msg)
print(r) # HTTP 통신 상태 확인
#요청 테스트 확인
mydict = r.json()
mydict

#위도와 경도 추출
point=mydict["response"]["result"]["point"]
print(point["x"],point["y"])

STEP4. 위경도를 조회하는 함수 정의
위경도를 조회하는 함수 정의
위에서 테스트로 확인한 과정을 함수로 정의
def get_point(addr,type ="road"):
#요청 url
url = "https://api.vworld.kr/req/address?"
key = "1C1C7AC9-4A35-3854-BFE7-D91FAEDD655E"
#요청 파라미터 (명세서 확인)
params = {
"service": "address",
"request": "getcoord",
"crs": "epsg:4326",
"address": addr,
"format": "json",
"type": type,
"key": key
}
#웹에 데이터 요청하기
with requests.Session() as session:
#세션 객체에 웹 브라우저 정보 (UserAgent) 주입 (웹서버가 파이썬 프로그램을 정상적인 웹 브라우저로 여기도록)
session.headers.update({"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
})
r=session.get(url,params=params) #get 메서드로 접근하고, 파라미터 값 쿼리 스트링 형태로 전달
print(r.url)
if r.status_code !=200:
msg ="[%d Error] %s 에러가 발생함" % (r.status_code,r.reason)
raise Exception(msg)
mydict = r.json()
point=mydict["response"]["result"]["point"]
return (point["x"],point["y"])

STEP.5-1 위경도 변환하기 | 동기 방식
- OPEN API 를 활용하기 위해서는 주소지 정보를 넣어 경도와 위도 값을 반환해야하고,
해당 과정을 get_point() 라는 함수로 정의한 상황. 이 함수를 쓰려면 주소 정보를 get_point() 함수에 파라미터로 전달해야 하므로, 우선 csv_list 에서 주소 정보를 추출한다.
- 추출한 주소 정보를 get_point() 함수에 넣으면 경도와 위도 정보가 나오는데, 만약 기본값으로 세팅한 type=road 에서 변환이 되지 않았다면 , 지번 주소로 재시도 하는 예외 처리를 걸어준다
- 만약 지번 주소에서도 예외로 처리되면 그때는 위도와 경도에 None 값을 넣어준다
- 기존에 존재하던 csv_list 데이터의 각 항목들에 위도와 경도를 추가해주고, 이 결과를 비워진 리스트 resultset에 넣어주면 리스트 내에 각 데이터들이 또 다른 리스트 형태로 존재하는 2차원 구조의 데이터가 완성된다
size = len(csv_list)
resultset=[]
for i,v in enumerate(csv_list[1:]): #제목을 건너뛰기 위해 1부터
print("%d/%d 진행중..."%(i+1,size))
items=v.strip().split(",")
try:
lat,lon = get_point(items[5])
except Exception as e :
try:
lat,lon =get_point(items[6],type="parcel")
except Exception as e2:
lat =None
lon=None
items.append(lat)
items.append(lon)
resultset.append(items)
resultset


STEP.5-2 위경도 변환하기 | 비동기 방식
- 비동기식 작업은 반복해서 실행해야하는 함수가 정의되어 있으면, worker 들이 스레드에서 해당 함수 작업을 하는 프로세스를 빈 리스트에 넣어주고, 나중에 그 프로세스들에 대한 결과 for 구문으로 탐색해면 빠르게 작업된 결과물들에 접근할 수 있게 된다
- 여기서는 위에서 정의한 get_point 함수를 일거리로 보내주고, 그 작업을 processes 리스트에 넣어준다
- processes 리스트를 result() 메서드로 탐색하면 결과값을 lat 과 lon 으로 받아온다
- 새롭게 추가된 lat 과 lon 은 csv_list 문자열을 요소별로 items 리스트로 만든 다음 해당 리스트에 append 해주고, append 된 리스트 결과를 resultset 에 하나씩 차곡차곡 쌓아준다
size = len(csv_list)
resultset=[]
processes=[] # 비동기 작업 프로세스를 저장할 리스트
with futures.ThreadPoolExecutor(max_workers=30) as executor:
for i,v in enumerate(csv_list[1:]): #제목을 건너뛰기 위해 1부터
print("%d/%d 진행중..."%(i+1,size))
items=v.strip().split(",")
pro=executor.submit(get_point,items[5])
processes.append(pro) #위에서 준비한 리스트에 저장
for i,p in enumerate(processes) : #비동기 프로세스가 실행되는 동안 발생하는 예외에 대비하기 위한 처리
try:
lat,lon = p.result()
except Exception as e :
try:
lat,lon =get_point(items[6],type="parcel")
except Exception as e2:
lat =None
lon=None
items=csv_list[i+1].strip().split(",")
items.append(lat)
items.append(lon)
resultset.append(items)
resultset

STEP.6 변환 결과 저장하기
- 리스트 안에 리스트 형식으로 각 행들이 쌓여져 있는 상황,resultset 리스트를 탐색해주고, 각 리스들의 값을 순서대로 딕셔너리에 반복해서 넣어준다. 이 딕셔너리를 비워져있는 리스트에 넣고, 해당 결과물을 데이터 프레임으로 바꿔주면 엑셀 형태로 다운받을 수 있게 된다
new_resultset = []
for r in resultset:
item_dict = {
"역번": r[0],
"역번호": r[1],
"호선": r[2],
"역명": r[3],
"역전화번호": r[4],
"도로명주소": r[5],
"지번주소": r[6],
"위도": r[7],
"경도": r[8]
}
new_resultset.append(item_dict)
df = DataFrame(new_resultset)
df.to_excel("지하철역.xlsx")
df

'빅데이터 국비 교육' 카테고리의 다른 글
| [아이티윌 빅데이터 52기] LAB 13 | 웹 페이지 데이터 수집하기 (연구과제) (0) | 2025.11.07 |
|---|---|
| [아이티윌 빅데이터 52기] LAB 13 | 파이썬 파이널 과제 | OpenAPI 연동 실습 (개인 작성 버전) (0) | 2025.11.07 |
| [아이티윌 빅데이터 52기] LAB 12 | 웹 데이터 수집하기 | 네이버 트렌드 데이터 API (0) | 2025.11.05 |
| [아이티윌 빅데이터 52기] LAB 12 | 웹 데이터 수집하기 | 카카오 개발자 API | 책 검색 결과 수집 2 | 반복문으로 전체 데이터/표지 이미지 가져오기 (0) | 2025.11.05 |
| [아이티윌 빅데이터 52기] LAB 12 | 웹 데이터 수집하기 | 카카오 개발자 API | 책 검색 결과 수집 (0) | 2025.11.05 |