[E&C] 05. 셀프 주유소 가격 분석

28025 단어 CrawlingEDACrawling

작업 환경

  • python 3.8
directory 구조
ds_stdy
├── data 	# 데이터 폴더
├── driver 	# driver 폴더
└── source_code # 작업 위치

코드

목적

  • 셀프 주유소가 일반 주유소보다 저렴한지 알아보기
  • 셀레니움을 이용해 데이터 추출

셀프 주유소 사이트 분석

웹페이지 추출 모듈 가져오기

  • selenium : 동적 페이지 데이터 추출 모듈
    • Chrome 브라우저 사용이 편함
    • Chrome 브라우저에 맞는 driver를 찾아 이용
from selenium import webdriver

셀레니움으로 접근

url = "https://www.opinet.co.kr/searRgSelect.do"
driver = webdriver.Chrome(""../driver/chromedriver.exe")
driver.get(url)
  • driver에 접근하려는 페이지를 넣어 구동

사이트 구조 파악

작업 설명
1. 홈페이지 접속
2. 접근 URL 다시 요청
3. 서울시 구를 하나씩 바꿔가며 선택
4. 엑셀 다운로드
# 페이지 접근 
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)

base_url = 'https://www.opinet.co.kr/searRgSelect.do'
driver.get(base_url)

# 화면을 최대화
driver.maximize_window() 
time.sleep(3)

driver.get(base_url)
time.sleep(3)
  • 페이지를 다시 접근해 데이터를 추출 할 준비
<!--서울시 구 태그 -->
<select style="width:102px;" id="SIGUNGU_NM0" name="SIGUNGU_NM0">
    <option value="">시/군/구</option>
    <option value="강남구" selected="selected" data-gis="">강남구</option>
</select>

<!-- 엑셀 저장 태그 -->
<div class="d_right">
    <a class="btn_type6_ex_save" href="javascript:fn_excel_download('os_btn');" id="glopopd_excel" title="새창열림:엑셀저장">
        <span>엑셀저장</span>
    </a>
</div>
  • SIGUNGU_NM0 : 구 이름 추출
  • glopopd_excel : 엑셀 저장 버튼

데이터 추출 및 전처리

하나의 값을 가져와 확인해 보기

gu_list_raw = driver.find_element_by_id('SIGUNGU_NM0') # 부모태크
gu_list = gu_list_raw.find_elements_by_css_selector('option') # 자식태그

# 구 이름 추출
gu_names = [option.get_attribute('value') for option in gu_list]
gu_names = gu_names[1:]
gu_names[:5], len(gu_names)
(['강남구', '강동구', '강북구', '강서구', '관악구'], 25)
  • 위에서 본 태그를 이용해 구 이름 추출

데이터 가져오기

for gu_name in tqdm_notebook(gu_names):
    gu_tag = '#SIGUNGU_NM0'
    gu = driver.find_element_by_css_selector(gu_tag)
    gu.send_keys(gu_name)
    time.sleep(2)
        
    excel_down = driver.find_element_by_id('glopopd_excel') # id로 찾을 땐 '#'을 쓰지 않음
    excel_down.click()
    time.sleep(2)

    if os.path.isfile('지역_위치별(주유소).xls'):
        os.rename('지역_위치별(주유소).xls', f'지역_위치별(주유소)_{gu_name}.xls')
    time.sleep(2)

driver.close()
  • 구 이름 추출 후 반복문을 통해 엑셀 다운로드

데이터 정리하기

파일 이름 불러오기

  • glob : 폴더에 존재하는 파일 목록 가져오기
import pandas as pd
from glob import glob

station_files = glob('/content/gdrive/MyDrive/Colab Notebooks/dataset/지역_*.xls')

data = []

for station_file in station_files:
    data.append(pd.read_excel(station_file, header=2))
    
station_raw = pd.concat(data)
station_raw.head()
  • 데이터를 살펴보면 휘발유의 가격이 -로 나타난 경우가 있음
    • - 값 처리후 float으로 형변환
  • 데이터가 합쳐져 인덱스 값이 제대로 돼 있지 않음
    • 인덱스를 새로 지정
  • 주소 컬럼을 이용해 구 이름 추출
  • 필요 없는 컬럼 제거

데이터 전처리

station = station_raw[['상호', '주소', '상표', '셀프여부', '휘발유']]
station = station[station['휘발유'] != '-']
station.rename(
    columns = {
        '휘발유' : '가격',
        '셀프여부' : '셀프'
    },
    inplace=True
)
station['가격'] = station['가격'].astype(float)
station.reset_index(inplace=True)
station.drop(labels='index', axis=1, inplace=True)
station.tail()

주유 가격 시각화

박스 플롯

plt.figure(figsize=(12, 8))
sns.boxplot(x="셀프", y="가격", data=stations, palette="Set1")
plt.grid(True)
plt.show()
  • 셀프 주유소의 가격이 일반 주유소보다 더 낮게 책정 돼 있음
  • 일반 주유소의 경우 가격의 폭이 셀프 주유소보다 큰 편
plt.figure(figsize=(12, 8))
sns.boxplot(x="상표", y="가격", hue="셀프", data=stations, palette="Set3")
plt.grid(True)
plt.show()
  • 알뜰 주유소가 다른 주유소에 비해 가격이 싼 편
    • 가격 변동도 크지 않음
  • 저렴한 가격에 주유를 하고 싶으면 셀프 알뜰 주유소에 가는 것도 나쁘지 않을 듯
plt.figure(figsize=(15, 12))
sns.boxplot(x="구", y="가격", hue="셀프", data=stations, palette="Set3")
plt.grid(True)
plt.show()
  • 가격이 안정적이고 전체적으로 싼 곳은 중량구, 강북구, 도봉구가 있음
  • 일부 지역을 제외하면 셀프 주유소가 더 낮은 가격으로 판매
  • 하지만 일반 주유소의 경우 가격이 천차 만별이라 셀프 주유소에 가는 것이 조금 더 이득일 수 있음

지도 시각화

위/경도 정보 갖고오기

import json
import folium
import googlemaps
import numpy as np

for idx, row in tqdm_notebook(stations.iterrows()):
    station_name = row['주소']
    results = gmaps.geocode(station_name, language='ko')
    
    lat = results[0].get('geometry')['location']['lat']
    lng = results[0].get('geometry')['location']['lng']
    
    stations.loc[idx, 'lat'] = lat
    stations.loc[idx, 'lng'] = lng
  • Google Map API이용해 위/경도 데이터 가져오기
geo_path = '02._skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))

my_map = folium.Map(location=[37.5502, 126.982], zoom_start=10.5, tiles='Stamen Toner')
my_map.choropleth(
    geo_data = geo_str,
    data = gu_data,
    columns = [gu_data.index, '가격'],
    key_on = 'feature.id',
    fill_color='PuRd'
)
my_map
  • 도심 지역보단 외곽 지역의 휘발유 가격이 낮음

결론

  • 도심보단 도심 주변이 가격이 저렴
  • 셀프 주유소가 일반 주유소보다 저렴
    • 저렴한 일반 주유소의 가격이 엄청 날뛰므로 셀프로 가는게 더 정신건강에 이로울듯
  • 셀프 주유를 하려면 알뜰 주유소를 들릴 것

좋은 웹페이지 즐겨찾기