[EDA] mini project 6 _ 서울시 저렴한 주유소 찾기 (2)

jaam._.mini·2023년 12월 7일
0
post-thumbnail
  1. 프로젝트명 : 서울시 저렴한 주유소 알아보기
    https://www.opinet.co.kr/searRgSelect.do

  2. 목표
    사이트 구조 확인
    브랜드
    가격
    셀프 주유 여부
    위치





import


from selenium import webdriver





페이지 접근


!팝업으로 인해 접근이 되지 않는 경우

  1. 메인 화면 접근
driver.switch_to_window(driver.window_handles[-1])
  1. 팝업창 닫기
 driver.close()
  1. 메인 화면 접근
driver.switch_to_window(driver.window_handles[-1])
  1. 접근 페이지 다시 요청
driver.get()
  1. 예시
import time

def main_get():
    # 페이지 접근
    url = 'https://www.opinet.co.kr/searRgSelect.do'
    driver = webdriver.Chrome(executable_path='../driver/chromedriver.exe') 
    driver.get(url)
    
    # 팝업 전환
    driver.switch_to_window(driver.window_handles[-1])
    
    #팝업창 닫기
    driver.close()
    
    # 메인 화면 전환
    driver.switch_to_window(driver.window_handles[-1])
    
    # 접근 페이지 다시 요청
    driver.get(url)

main_get()
url = 'https://www.opinet.co.kr/searRgSelect.do'
driver = webdriver.Chrome(executable_path='../driver/chromedriver.exe') 
driver.get(url)





데이터 가져오기


1. 시/도 데이터 가져오기

  • 부모 태그 가져오기
# 지역: 시도

# 부모 태그 먼저 가져오기
sido_list_raw = driver.find_element(By.CSS_SELECTOR, '#SIDO_NM0')
sido_list_raw.text
  • 자식 태그 가져오기

    # select > option 정보가 필요
    # TAG_NAME 선택 시 option 정보가 많으니까, find_elements 복수형태로 입력

sido_list = sido_list_raw.find_elements(By.TAG_NAME, 'option')
len(sido_list), sido_list[1].text
# 서울(option) > 서울특별시(option value)
# value 로  fullname을 불러옴

sido_list[1].get_attribute('value')
  • for()로 데이터 모으기
# 빈리스트 하나 만들어 줌
sido_names =[]

# for()문으로 option 값 들을 가져오고 싶음

# (1)번 방법
# for option in sido_list:
#     sido_names.append(option.get_attribute('value'))

# sido_names

#(2)번 방법 ★★한줄 작성
sido_names = [option.get_attribute('value')for option in sido_list]
sido_names
# 맨앞 빈칸 처리
sido_names = sido_names[1:]
sido_names



2. 시 값 변경해서 넣어주기

# 제주도로 넣어주기

    # 부모 태그 먼저 가져오기
    # sido_list_raw = driver.find_element(By.CSS_SELECTOR, '#SIDO_NM0')
    
    # sido_names = [option.get_attribute('value')for option in sido_list]
    # sido_name[16] : '제주특별자치도'

sido_list_raw.send_keys(sido_names[16])



3.구 데이터 가져오기

# 부모 태그 먼저 가져오기
gu_list_raw = driver.find_element(By.CSS_SELECTOR, '#SIGUNGU_NM0')

# 자식 태그 가져오기
gu_list = gu_list_raw.find_elements(By.TAG_NAME, 'option')

# for() : 하나씩 정보 가져오기
gu_names = [option.get_attribute('value')for option in gu_list]
gu_names = gu_names[1:] # 맨 앞 공백 1개 빼기 위해  
gu_names
gu_list_raw.send_keys(gu_names[15])



4. 엑셀 저장(방법)

둘 중 한 방법 사용하면 됨

driver.find_element(By.CSS_SELECTOR, '#glopopd_excel').click()
driver.find_element(By.XPATH, '//*[@id="glopopd_excel"]/span').click()



5. 서울시 전체구, 엑셀 다운 받기

  • 알아서 입력, 클릭, 엑셀 다운로드 됨...😱
# 시간 소요 오류 방지
import time

# tqdm_notebook을 이용
from tqdm import tqdm_notebook

#for()으로 데이터 수집
for gu in tqdm_notebook(gu_names):
#tqdm_notebook : 얼만큼 진행되는지 눈으로 확인하기 위해 사용
    
    element = driver.find_element(By.CSS_SELECTOR, '#SIGUNGU_NM0')
    # 부모 태그 
    
    element.send_keys(gu)
    # 키 값(모든 구들)을 하나씩 보내 줌
    
    time.sleep(3)
    # 한번 걸어 줌

    element_get_excel = driver.find_element(By.CSS_SELECTOR, '#glopopd_excel').click()
    # 엑셀 저장
    
    time.sleep(3)
    # 한번 걸어 줌





가격 정보 정리


# glob
# 파일의 목록을 읽어 오고 정리해 줌

import pandas as pd
from glob import glob



1. 파일 목록 한번에 가져오기

glob('../data/지역_*.xls')



2. 파일명 저장

stations_files = glob('../data/지역_*.xls')
stations_files[:5]

# test : 하나만 읽어와 보기

tmp = pd.read_excel(stations_files[0])
tmp.tail(2)

# 엑셀 파일을 열어보면 1~2줄은 데이터가 없어서 위와 같이 출력 됨
# 예쁘게 출력하기 위해 아래와 같은 코드를 써야 함
# 2번째 이후 부터 컬럼을 가져와라..!

tmp = pd.read_excel(stations_files[0], header=2)
tmp.tail(2)

# stations_files = glob('../data/지역_*.xls') : 모든 엑셀 취합 명령
# tmp = pd.read_excel(stations_files[0], header=2) : 엑셀 읽어오기 명령

tmp_raw = []

for file_name in stations_files:
    tmp = pd.read_excel(file_name, header=2)
    tmp_raw.append(tmp)

tmp_raw



3. pd.concat() : 형식이 동일, 연달아 붙이고 싶을때 사용

# 위 자료를 데이터 프레임 형식으로 변환
station_raw = pd.concat(tmp_raw)
station_raw

station_raw.info()



4. 필요하나 컬럼 정리

# 어떤 컬럼들이 있는지 확인
station_raw.columns
stations = pd.DataFrame({
    '상호' : station_raw['상호'],
    '주소' : station_raw['주소'],
    '가격' : station_raw['휘발유'],
    '셀프' : station_raw['셀프여부'],
    '상표' : station_raw['상표']
})
stations.tail()



5. 구 컬럼 만들기

for eachAddress in stations['주소']:
    print(eachAddress.split()[0])
stations['구'] = [eachAddress.split()[1] for eachAddress in stations['주소']]
# 구, 컬럼 = [eachDDRESS 를 잘라서 1번째만 가져온다, station['주소']에서 하나씩 뽑아서]

stations

stations['구'].unique(), len(stations['구'].unique())



6.가격 데이터 변환 object > float

stations['가격'] = stations['가격'].astype('float')
  • 가격 정보가 없는 주유소
stations[stations['가격'] == '-']
  • 가격표가 없는 것들은 사용하지 않는다
stations = stations[stations['가격'] != '-']
stations.tail()
stations['가격'] = stations['가격'].astype('float')
stations.info()
stations



7. 인덱스 재정렬

stations.reset_index(inplace=True)
stations.tail()
stations.head()



8. 인덱스 컬럼 지우기

del stations['index']
stations.head()





자료 시각화


# 한글 설정
import matplotlib.pyplot as plt
import seaborn as sns
import platform
from matplotlib import font_manager, rc

get_ipython().run_line_magic("matplotlib", "inline")
# %matplotlib inline

path = "C:/Windows/Fonts/malgun.ttf"

rc("font", family="Malgun Gothic")

# if platform.system() == "Darwin":
#     rc("font", family="Arial Unicode MS")
# elif platform.system == "Windows":
#     font_name = font_manager.Fontproperties(fname=path).get_name()
#     rc("font", family=font_name)
# else:
#     print("Unkown system. sorry~~")



1. boxplot(_pandas)

stations.boxplot(column='가격', by='셀프', figsize=(8,8))



2. boxplot(_seaborn)

plt.figure(figsize=(8,8))
sns.boxplot(x='셀프', y='가격', data=stations, palette='Set3')
plt.grid(True)
plt.show()

# 구분기준 : hue='셀프'

plt.figure(figsize=(8,8))
sns.boxplot(x='상표', y='가격',  hue='셀프',data=stations, palette='Set1')
plt.grid(True)
plt.show()



3. 지도 시각화

  • import 설정
import json
import folium

#경고 문구가 뜨는게 싫어서 설정.
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
  • numpy - pivot_table
# 가격 표현방식 = 평균값 : aggfunc=np.mean

import numpy as np

gu_data = pd.pivot_table(data=stations, index='구', values='가격', aggfunc=np.mean)
gu_data.head()

geo_path = "../data/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='cartodb positron',
)

# Choropleth :경계선 좌표값 표시하기
folium.Choropleth(
    geo_data=geo_str, # 우리나라 경계선 좌표값이 담긴 데이터
    data=gu_data,
    columns=[gu_data.index, "가격"],
    key_on="feature.id",
    fill_color="PuRd",
).add_to(my_map)

my_map

profile
비전공자의 데이터 공부법

0개의 댓글