Data Analysis/청소년수련활동인증제

공공데이터 api 활용 수집 이후 추가데이터수집 보완

mansoorrr 2023. 8. 8. 17:45

naver api를 활용해 추가데이터 수집을 했다. 그런데 빈 데이터가 너무 많아 사용하기가 어려웠다.

그래서 새로운 방법을 생각했다. 이 데이터는 원래 e-청소년 홈페이지에서 확인할 수 있는 데이터였다. 그러니 기관에 대한 정보가 다 있을것이라고 판단했다. 따라서. 기관 이름만 가지고 e- 청소년 홈페이지에 등록되어있는 주소를 먼저 가져왔다.

 

그 후 가져온 주소의 모양을 통일하고 좌표도 갖기 위해 geocoding api를 사용했다. e-청소년 사이트에서 가져온 주소는 정제가 되어있지 않아 깔끔하지 않았다. 하지만 geocoding api를 활용하면 자체적으로 일치하는 부분만 가지고 원하는 정보를 가져올 수 있었다. 

 

만들다 보니 데이터가 너무 더럽게 저장되어있어서 다시 table을 다시 만들 생각을 했다. 이번에 수집하는 데이터로 기관에 대한 모든 정보만 갖는 테이블을 만들고자 한다.

 

db에서 먼저 데이터를 그룹지어 가져왔다.

#---------- read data
data_sql = """
    SELECT orgName, address, roadAddress
    FROM orginfo
    GROUP BY orgName, address, roadAddress;
"""

data = read_table(data_sql)
columns = ["orgName", "address", "roadAddress"]
df = pd.DataFrame(data, columns=columns)
print(df.shape)

 

이후 기관 이름만 가지고 e-청소년 홈페이지에서 기관 주소만 추출했다. 추출한 데이터는 힘을 많이 들이지 않는 한에서 최대한 정제 했다. 이 주소를 가지고 api를 활용해 위도와 경도를 추출했고, 역으로 위도와 경도를 가지고 정제된 주소를 만들어 내었다.

#---------- data scraping(e-청소년 홈페이지 크롤링 > geocoding api)
org_names = df['orgName'].tolist()
for idx, org_name in enumerate(org_names[324:]):

    org_info_dict = {}

    orgName = quote_plus(org_name)
    url = f"https://www.youth.go.kr/m/yap/operInsttGuidance/operInsttLstForm.mo?sort=&order=&page=1&rows=&kFcltySn=&nas.cmm.token.html.TOKEN=a79580f179c0d392ce18d13e8aea15c5&sCtprvnCode=&sFcltyNm={orgName}"

    res = requests.get(url)
    soup = bs(res.content, 'html.parser')
    # ---------------- 최소한의 정제
    try:
        name_box = soup.select_one("div.act-name-box")
        address = name_box.select("dd")[0].get_text().strip().replace("주소 :  ", "").split("(")[0]
        address = re.sub('[^가-힣0-9-~ ]', "", address).split(org_name)[0]
    except:
        address = "nodata"


    #---------- geocoding
    geo_url = f"https://maps.googleapis.com/maps/api/geocode/json?address={address}&key={GEO_KEY}"
    params = {'language':'ko'}
    res = requests.get(geo_url, params=params)
    geo_json = res.json()

    try:
        lat = geo_json['results'][0]['geometry']['location']['lat']
        lng = geo_json['results'][0]['geometry']['location']['lng']

        org_info_dict["orgName"] = org_name
        org_info_dict["orgAddress"] = address
        org_info_dict["lat"] = lat
        org_info_dict["lng"] = lng

        #---------- reverse geocoding
        reverse_geo_url = f"https://maps.googleapis.com/maps/api/geocode/json?latlng={org_info_dict['lat']},{org_info_dict['lng']}&key={GEO_KEY}"
        params = {"language":"ko"}
        res = requests.get(reverse_geo_url, params=params)
        res_json = res.json()

        road_address = res_json["results"][0]["formatted_address"]

        org_info_dict['roadAddress'] = road_address
        # -------------------- 중략
        insert_table(insert_sql)

    except:
        # ----------------------중략
        insert_table(insert_sql)

이렇게 해서 727건의 기관에 대한 정보를 따로 table을 저장했다. 7건의 데이터에 대한 정보를 찾지 못했는데 이건 그냥 손으로 찾아서 채우는게 빠를듯 하다. 나머지 데이터를 좀 만져야 할 것 같은데, 이는 Mysql을 통해 테이블 정리를 해야할것 같다.

 

 

데이터정제 1 - 데이터 하나만 남도록 설정

추가데이터수집 보완 naver api를 활용해 추가데이터 수집을 했다. 그런데 빈 데이터가 너무 많아 사용하기가 어려웠다. 그래서 새로운 방법을 생각했다. 이 데이터는 원래 e-청소년 홈페이지에서

hiphan-mansoorrr.tistory.com