서울자전거 따릉이 대여소 시각화(1) - 위치 크롤링

게시일 : 2017년 11월 19일     수정일 : 2018년 11월 30일    
# Crawling # Python # Requests # BeautifulSoup

Requests와 BeautifulSoup 라이브러리를 활용한 따릉이 대여소 크롤링

서울 열린 데이터 광장에 업로드된 파일은 최신 대여소 정보가 누락되어 활용하기 어렵다.

크롤링에 필요한 라이브러리

from tqdm import tqdm # 진행률 파악 용도
import random
from bs4 import BeautifulSoup as bs
import pandas as pd
import time
import requests

따릉이 홈페이지에서는 지도를 통해 대여소의 위치와 대여가능한 자전거 수를 보여준다. https://www.bikeseoul.com/app/station/moveStationSearchView.do?currentPageNo=1

처럼 URL을 활용하면 대여소 정보를 크롤링할 수 있다.

# 대여소 정보를 담을 List
locations=[]
# 기본 url (페이지 넘버링만 추가하면 된다)
base_url = 'https://www.bikeseoul.com/app/station/moveStationSearchView.do?currentPageNo='
# 크롤링 함수 선언
def crawling_bike(start, end):
    for num in tqdm(range(start,end+1)):
        # 반복문으로 url에 페이지 수만 바꿔서 추가하면 된다.
        page = requests.get(base_url + str(num)) 
        soup = bs(page.text)
        # 데이터가 있는 table 태그에 접근
        loc_table = soup.select('table.psboard1 > tbody')[0].find_all('tr')
        for row in loc_table:
            loc_info = []
            # <번호. 대여소명>에서 번화와 대여소명 각각 처리
            loc_name = row.select('td.pl10')[0].get_text(strip=True)
            if '.' in loc_name:
                loc_info.append(loc_name.split('.')[0]) # 번호 추출
                loc_info.append(loc_name.split('.')[-1].lstrip()) # 대여소명 추출
            else:
                loc_info.append(0) # 번호가 없는 경우 0으로 처리
                loc_info.append(loc_name)
            # 거치대수
            loc_info.append(row.select('td.tr')[0].get_text(strip=True))
            # 주소
            loc_info.append(row.select('td.mhid')[0].get_text(strip=True))
            # 위도, 경도 좌표
            loc_geo = row.find('a')['param-data'].split(',')
            loc_info.append(loc_geo[0])
            loc_info.append(loc_geo[1])
            # 리스트에 location 추가
            locations.append(loc_info)
        # 트래픽 속도 조절을 위한 random time 설정    
        time.sleep(random.random()*2)

데이터프레임으로 만들고 CSV파일로 저장할 수 있다.

# 시작과 마지막 페이지를 arguments로 입력
crawling_bike(1,3)
# List를 데이터프레임으로 변환
header = ['번호','대여소','거치대수','주소','위도','경도']
df = pd.DataFrame.from_records(locations, columns = header)
# csv파일로 추출
df.to_csv('seoulbike.csv', index=False)

따릉이 대여소 정보를 확인할 수 있다.

주소는 도로명 주소와 구 주소가 함께 들어있어 전처리가 필요하다.

df_seoulbike

이어서, 시각화(2)로 이동

Link :