[EDA분석_2]셀프주유소가 저렴한가? (세차장, 경정비, 편의점, 24시간영업 중 하나 이상 포함된 주유소)

TaeHwi Kang·2022년 11월 2일
0

1. 서울 (세차장,경정비,편의점, 24시간 영업)중 하나 이상 포함된 주유소 데이터 가져오기

1) 오피넷 사이트 셀레니움으로 접근하기

# 오피넷 사이트-> 싼 주유소찾기 -> 지역별 접속
from selenium import webdriver
import time

driver = webdriver.Chrome("../driver/chromedriver.exe")
url = "https://www.opinet.co.kr/searRgSelect.do"
driver.get(url)
time.sleep(1)
driver.get(url)

# 부가정보 선택
# 세차장 선택
xpath_wash ='//*[@id="CWSH_YN"]'
tag_wash = driver.find_element_by_xpath(xpath_wash)
tag_wash.click()

# 경정비 선택
xpath_repair ='//*[@id="MAINT_YN"]'
tag_repair = driver.find_element_by_xpath(xpath_repair)
tag_repair.click()

# 편의점 선택
xpath_store ='//*[@id="CVS_YN"]'
tag_store = driver.find_element_by_xpath(xpath_store)
tag_store.click()

# 24시간 선택
xpath_24h ='//*[@id="SEL24_YN"]'
tag_24h = driver.find_element_by_xpath(xpath_24h)
tag_24h.click()

# 서울 모든 '구' 받아 오기
gu_names = []

for option in gu_list:
    gu_names.append(option.get_attribute("value"))

# gu_names에서 비어있는 인덱스 제거
gu_names = gu_names[1:]


2) 주유소 별 상세정보 가져오기 테스트

import pandas as pd
from urllib.request import urlopen, Request
from bs4 import BeautifulSoup

# 구별 주유소 갯수 확인
int(driver.find_element_by_xpath('//*[@id="totCnt"]').text)
    
# 검색된 주유소 개별 클릭
driver.find_element_by_css_selector('#body1 > tr:nth-child(12) > td.rlist > a').click()

# 구별 검색된 페이지 BeautifulSoup으로 가져오기
oil_req2 = driver.page_source
oil_soup2 = BeautifulSoup(oil_req2, "html.parser")
print(oil_soup2.prettify())

# 상세정보창이 페이지창에 걸려 지도 크기 조절후 정보 가져오기
# 지도 확대/축소
driver.find_element_by_xpath('//*[@id="map_div"]/div[4]/div[2]/div[2]/div/div[3]').click()
time.sleep(1)
driver.find_element_by_xpath('//*[@id="map_div"]/div[4]/div[2]/div[2]/div/div[6]').click()

# 주유소 별 셀프주유소 정보
if oil_soup2.find("tbody").find_all("tr")[8].find("span"):
        if oil_soup2.find("tbody").find_all("tr")[8].find("span").text == "셀프":
            print("y")
        else: 
            print("n")  
else: 
    print("n")
    
# 세차장 유무 정보
if oil_soup2.find("div",{"class","service"}).find("img", {"id":"cwsh_yn"})["src"] == "/images/user/gis/oil_station_service1_01.gif":
    print("y")
else: 
    print("n")

# 충전소 유무 정보
if oil_soup2.find("div",{"class","service"}).find("img", {"id":"lpg_yn"})["src"] == "/images/user/gis/oil_station_service1_02_01.gif":
    print("y")    
else: 
    print("n")

# 경정비 유무 정보
if oil_soup2.find("div",{"class","service"}).find("img", {"id":"maint_yn"})["src"] == "/images/user/gis/oil_station_service1_03.gif":
    print("y")
    
else: 
    print("n")

# 편의점 유무 정보
if oil_soup2.find("div",{"class","service"}).find("img", {"id":"cvs_yn"})["src"] == "/images/user/gis/oil_station_service1_04.gif":
    print("y")
    
else: 
    print("n")
    
# 24시간영업 정보
if oil_soup2.find("div",{"class","service"}).find("img", {"id":"sel24_yn"})["src"] == "/images/user/gis/oil_station_service1_05.gif":
    print("y")  
else: 
    print("n")
    
# 주유소 이름 정보
oil_soup2.find("div",{"class":"ollehmap-info-defaultStyle"}).find("label",{"id":"os_nm"}).text

# 주유소 주소 정보
oil_soup2.find("div",{"class":"overflow_gis_detail"}).find("label",{"id":"rd_addr"}).text

# 주유소 브랜드 정보
oil_soup2.find("div",{"class":"overflow_gis_detail"}).find("label",{"id":"poll_div_nm"}).text

# 주유소 별 휘발류 가격 정보
oil_soup2.find("div",{"class":"gis_detail_info_bcon mgt_15"}).find("label",{"id": "b027_p"}).text

# 주유소 별 경유 가격 정보
oil_soup2.find("div",{"class":"gis_detail_info_bcon mgt_15"}).find("label",{"id": "d047_p"}).text

3) 서울 (세차장,경정비,편의점 24시간영업)중 하나 이상 포함된 모든 주유소 정보 가져오기

from selenium import webdriver
import time

driver = webdriver.Chrome("../driver/chromedriver.exe")
url = "https://www.opinet.co.kr/searRgSelect.do"
driver.get(url)
time.sleep(1)
driver.get(url)
time.sleep(1)

xpath_wash ='//*[@id="CWSH_YN"]'
tag_wash = driver.find_element_by_xpath(xpath_wash)
tag_wash.click()

xpath_repair ='//*[@id="MAINT_YN"]'
tag_repair = driver.find_element_by_xpath(xpath_repair)
tag_repair.click()

xpath_store ='//*[@id="CVS_YN"]'
tag_store = driver.find_element_by_xpath(xpath_store)
tag_store.click()

xpath_24h ='//*[@id="SEL24_YN"]'
tag_24h = driver.find_element_by_xpath(xpath_24h)
tag_24h.click()

oil_name = []
oil_adrr = []
oil_brand = []
oil_self = []

oil_gasoline = []
oil_diesel  = []

oil_24h = []
oil_wash = []
oil_repair = []
oil_store = []
oil_charge = []
oil_gu = []

for gu in gu_names:
    element = driver.find_element_by_id("SIGUNGU_NM0")
    element.send_keys(gu)
    time.sleep(2)
    
    for num in range(1, int(driver.find_element_by_xpath('//*[@id="totCnt"]').text)+1):
        oil_gu.append(gu)
        
        driver.find_element_by_css_selector("#body1 > tr:nth-child(" + str(num) + ") > td.rlist > a").click()
        
        driver.find_element_by_xpath('//*[@id="map_div"]/div[4]/div[2]/div[2]/div/div[3]').click()
        time.sleep(1)
        
        
         
        oil_req2 = driver.page_source
        oil_soup2 = BeautifulSoup(oil_req2, "html.parser")
        
        oil_name.append(oil_soup2.find("div",{"class":"ollehmap-info-defaultStyle"}).find("label",{"id":"os_nm"}).text)
        oil_adrr.append(oil_soup2.find("div",{"class":"overflow_gis_detail"}).find("label",{"id":"rd_addr"}).text)
        oil_brand.append(oil_soup2.find("div",{"class":"overflow_gis_detail"}).find("label",{"id":"poll_div_nm"}).text)
        
        if oil_soup2.find("tbody").find_all("tr")[num-1].find("span"):
            if oil_soup2.find("tbody").find_all("tr")[num-1].find("span").text == "셀프":
                oil_self.append("Y")
            else: 
                oil_self.append("N")  
        else: 
            oil_self.append("N")
        
        oil_gasoline.append(oil_soup2.find("div",{"class":"gis_detail_info_bcon mgt_15"}).find("label",{"id": "b027_p"}).text)
        oil_diesel.append(oil_soup2.find("div",{"class":"gis_detail_info_bcon mgt_15"}).find("label",{"id": "d047_p"}).text)


        if oil_soup2.find("div",{"class","service"}).find("img", {"id":"cwsh_yn"})["src"] == "/images/user/gis/oil_station_service1_01.gif":
            oil_wash.append("Y")
        else: 
            oil_wash.append("N")

        if oil_soup2.find("div",{"class","service"}).find("img", {"id":"lpg_yn"})["src"] == "/images/user/gis/oil_station_service1_02_01.gif":
            oil_charge.append("Y")    
        else: 
            oil_charge.append("N")

        if oil_soup2.find("div",{"class","service"}).find("img", {"id":"maint_yn"})["src"] == "/images/user/gis/oil_station_service1_03.gif":
            oil_repair.append("Y")
        else: 
            oil_repair.append("N")

        if oil_soup2.find("div",{"class","service"}).find("img", {"id":"cvs_yn"})["src"] == "/images/user/gis/oil_station_service1_04.gif":
            oil_store.append("Y")
        else: 
            oil_store.append("N")
    
        if oil_soup2.find("div",{"class","service"}).find("img", {"id":"sel24_yn"})["src"] == "/images/user/gis/oil_station_service1_05.gif":
            oil_24h.append("Y")  
        else: 
            oil_24h.append("N")
     
        driver.find_element_by_xpath('//*[@id="map_div"]/div[4]/div[2]/div[2]/div/div[6]').click()
        time.sleep(1)

4) 데이터 정리

# 가져온 데이터 DataFrame으로 만들기
import pandas as pd

oil_seoul_data = {
    "name" : oil_name,
    "address" : oil_adrr,
    "brand" : oil_brand,
    "gasoline" : oil_gasoline,
    "diesel":oil_diesel, 
    "self" : oil_self,
    "wash":oil_wash,
    "charge":oil_charge, 
    "repair":oil_repair, 
    "store":oil_store, 
    "24hour":oil_24h, 
    "gu": oil_gu
    }
    
oil_df = pd.DataFrame(oil_seoul_data)

# 주소를 이용하여 경도,위도 값 DataFrame에 추가하기
import googlemaps

gmaps_key = "개인키값"
gmaps = googlemaps.Client(key=gmaps_key)

oil_lat = []
oil_lng = []

for num in range(len(oil_adrr)):
    target_name = oil_adrr[num]

    oil_lat.append(gmaps.geocode(target_name)[0].get("geometry")["location"]["lat"])
    oil_lng.append(gmaps.geocode(target_name)[0].get("geometry")["location"]["lng"])
    
oil_df["lat"] = oil_lat
oil_df["lng"] = oil_lng

# 휘발류, 경유 데이터타입 object에서 int 변경하기
# 휘발류, 경유 데이터를 "," 포함하여 가져와 "," 제거후 DataFrame에 적용 하기
for i in range(len(oil_gasoline)):
	oil_gasoline[i] = int(oil_gasoline[i].split(",")[0]+oil_gasoline[i].split(",")[1])
	oil_diesel[i] = int(oil_diesel[i].split(",")[0]+oil_diesel[i].split(",")[1])

oil_df["gasoline"] = oil_gasoline
oil_df["diesel"] = oil_diesel

5) 최종 DataFrame

2. 데이터 시각화

# '가솔린'과 '디젤'를 셀프주유 여부에 따라 비교 
oil_df.boxplot(column=["gasoline","diesel"], by="self", figsize=(12,8));

# '브랜드'별로 셀프주유 여부에 따라 '휘발류' 금액 비교
import seaborn as sns
import matplotlib.pyplot as plt

plt.figure(figsize=(12,8))
sns.boxplot(x="brand", y="gasoline", hue = "self", data = oil_df, palette="Set3")
plt.grid(True)
plt.show()

# '브랜드'별로 셀프주유 여부에 따라 '경유' 금액 비교
plt.figure(figsize=(12,8))
sns.boxplot(x="brand", y="diesel", hue = "self", data = oil_df, palette="Set3")
plt.grid(True)
plt.show()

# '구'별로 휘발류와 경유 금액차이 비교
plt.figure(figsize=(18,10))
sns.boxplot(x="gu", y="gasoline", hue = "self", data = oil_df, palette="Set1")
plt.grid(True)
plt.xticks(rotation=90)
plt.show()

3. 휘발유와 경유 가격이 셀프주유소가 보통주유소보다 저렴한지 분석해보기

1) '휘발유'와 '경유'의 가격으로 비교해 보았을때

  • 셀프 주유소가 보통 주유소 보다 휘발유와 경유의 가격 분포가 낮게 형성되어 있고 중위값이 더 저렴하다

2) '브랜드' 별로 비교해 보았을때

  • 브랜드의 셀프 주유소가 브랜드의 보통 주유소 보다 휘발유와 경유의 가격 분포가 낮게 형성되어 있고 중위값이 더 저렴하다

3) '구' 별로 비교해 보았을 때

  • '구' 별로 셀프 주유소가 보통 주유소 보다 휘발유와 경유의 가격 분포가 낮게 형성되어 있고 중위값이 더 저렴하다
  • 하지만 강남구의 셀프 주유소는 몇 곳의 다른 구들의 보통주유소보다 휘발유와 경유의 가격 분포와 중위값 모두 높다

- 결론 : 모든 셀프주유소의 '휘발유','경유'의 가격이 보통주유소 보다 모두 저렴하지는 않지만 대체로 저렴하다고 보여진다.

profile
스터디 노트

0개의 댓글