갓생사는 공순이가 되고싶은 콩순이 2022. 9. 2. 00:45
반응형

어울링 크롤링 및 지도 시각화

라이브러리 임포트

from urllib.request import urlopen
from bs4 import BeautifulSoup

import pandas as pd

어울링 크롤링

- 1) 데이터프레임 생성

data = pd.DataFrame(columns=['스테이션명', '위치', '상세정보', '위도', '경도'])

- 2) 세종시 어울링 사이트 접속 주소 준비 : https://www.sejongbike.kr/userStationAction.doprocess=stationTotalList&menu=21

 

세종특별자치시 공공자전거 어울링

64. 자이아파트 세종특별자치시 조치원읍 죽림리 376-1 119동 앞 Network 에러 바로가기

www.sejongbike.kr

url = 'https://www.sejongbike.kr/userStationAction.do?process=stationTotalList&menu=21'

- 3) url에서 HTML 가져오기

html = urlopen(url)

- 4) HTML 파싱해서 object 형태로 변환

bsObject = BeautifulSoup(html, 'html.parser', from_encoding='UTF-8')

- 5) 어울링 정류장 정보가 있는 table만 가져오기

table = bsObject.find_all('table', {'class', 'content_table'})

- 6) 상세 정보 추출하기

- 6-1) table 내에서 tr 찾기

tr = table[0].find_all('tr')

- 6-2) 첫 tr(테이블의 column 정보)은 제외

tr = tr[1:len(tr)]

- 6-3) 어울링 정류장 상세 정보 추출

for index_tr in range(0, len(tr)):
  td = tr[index_tr].find_all('td')

  # 장소
  station = td[0].text.split('.')[1].strip()

  # 위치
  location  = td[1].text.replace('\r\n', '').strip()

  # 상세정보
  condition = td[2].text

  # 좌표 추출 -> 위도와 경도가 같은 속성 안에 하나도 들어있음.
  onclick = td[3].a.attrs['onclick'] # javascript:openMapSize('23908500000001', '36.482114', '127.259628');
  
  # 위도
  lat = onclick.split(',')[1] # '36.482114'
  lat = lat.replace('\'', '').strip() # 작은따옴표를 없애기 위해서 replace를 해준 뒤 공백을 제거하기 위해서 strip()함수를 사용한다.

  # 경도
  lon = onclick.split(',')[2] #  '127.259628');
  lon = lon.replace(');', '').replace('\'', '').strip()

- 7) 어울링 정류장 상세정보 DataFrame에 담기(append) → 이거 for문안에 있어야 함.

  data = data.append({
      '스테이션명' : station,
      '위치' : location,
      '상세정보' : condition,
      '위도' : float(lat),
      '경도' : float(lon)}, ignore_index=True
  )
  print('Complets of' + station)

 : 마지막 print구문은 제대로 출력되고 있는지 확인하는 코드

data.head(25)

크롤링한 데이터 저장하기

data.to_csv('어울링 크롤링_20220831.csv', encoding='utf-8-sig', index=False)

지도 시각화

import folium
# 어울링 정류장의 상태정보에 따라서 Marker를 다르색으로 표시
data.상세정보.unique()
# 정상 -> 파랑, Network에러 -> 주황, 그외 -> 빨강

- 1) 수집한 어울링 대여소의 평균 좌표를 사용하여 지도 만들기

s_map = folium.Map(location=[data['위도'].mean(),data['경도'].mean()], zoom_start = 14)

- 2) 어울링 정류장 상태정보 병수 담기

condition = data.상세정보

- 3) 어울링 정류장 Marker 지도에 추가하기

for index_draw in range(0, len(condition)):
  if condition[index_draw] == '정상' :
    folium.Marker([data.loc[index_draw, '위도'], data.loc[index_draw, '경도']],
                   popup='<pre>'+data.loc[index_draw,'스테이션명']+'</pre>',
                   icon=folium.Icon(color='blue', icon = 'info-sign')).add_to(s_map)
  elif condition[index_draw] == 'Network 에러' :
    folium.Marker([data.loc[index_draw, '위도'], data.loc[index_draw, '경도']],
                   popup='<pre>'+data.loc[index_draw,'스테이션명']+'</pre>',
                   icon=folium.Icon(color='orange', icon = 'info-sign')).add_to(s_map)
  else : 
    folium.Marker([data.loc[index_draw, '위도'], data.loc[index_draw, '경도']],
                   popup='<pre>'+data.loc[index_draw,'스테이션명']+'</pre>',
                   icon=folium.Icon(color='red', icon = 'info-sign')).add_to(s_map)

s_map

 

LIST