데이터 크롤링
!pip install selenium #selenium 설치
from selenium import webdriver
driver = webdriver.Chrome('C:\data\chromedriver') #크롬... 가상의 창에서 작업
driver.get('http://naver.com') #네이버 사이트에서 활용하기!
네이버 사이트에서 로그인하는 크롤링을 할 예정!
xpath='//*[@id="account"]'
driver.find_element_by_xpath(xpath).click()
네이버 메인화면에서 로그인을 클릭하는 작업을 하는 코드
xpath를 통해 작업 수행
elem_login = driver.find_element_by_id('id')
elem_login.clear()
elem_login.send_keys('*********') #값을 입력하는 명령어
elem_login = driver.find_element_by_id('pw')
elem_login.clear()
elem_login.send_keys('**********')
********* 자리에는 각각 아이디와 비밀번호를 입력하면 됨!
여기서는 아이디 값을 사용해서 작업을 수행함
# 태그 오른쪽 클릭->Copy->xpath 밑에 붙여넣기
# find_element_by_xpath(xpath) : xpath 위치 찾기
# click() : 로그인 버튼 클릭하는 함수
xpath='//*[@id="log.login"]'
driver.find_element_by_xpath(xpath).click()
아이디와 비밀번호를 입력하고 로그인을 클릭하는 작업을 함!
그런데 비밀번호랑 아이디가 맞는건데도 로그인에 실패함..
두 번째 크롤링은 오피넷?에서 서울시 기름의 가격을 크롤링
from selenium import webdriver
driver = webdriver.Chrome('C:\data\chromedriver')
driver.get("http://www.opinet.co.kr") #메인화면
driver.get("http://www.opinet.co.kr/searRgSelect.do") #자료를 뽑아낼 주소
서울 주유소 가격을 추출할 것임!
# 서울 클릭을 위한 xpath 확인
area = driver.find_element_by_xpath('//*[@id="SIDO_NM0"]')
area.send_keys('서울')
서울 클릭
# 구/데이터 입력을 위한 xpath 확인
gu_list_raw = driver.find_element_by_xpath('//*[@id="SIGUNGU_NM0"]')
# 구 리스트 확인 위해 find_elements_by_tag_name으로 option 태그 검색
gu_list = gu_list_raw.find_elements_by_tag_name('option')
#value 속성을 이용하여 구 리스트 획득
gu_names = [option.get_attribute('value') for option in gu_list]
gu_names.remove('')
서울시 모든 구의 자료를 다운받을건데 먼저 잘 작동하는지 테스트 해 보기
#gu_names에서 리스트 첫번째 값 입력하여 테스트 진행
element = driver.find_element_by_id('SIGUNGU_NM0')
element.send_keys(gu_names[0])
#조회버튼의 Xpath를 찾아서 클릭
xpath ='''//*[@id="searRgSelect"]/span'''
element_sel_gu = driver.find_element_by_xpath(xpath).click()
#엑셀 저장 버튼 클릭하여 엑셀 내용 저장 테스트
xpath = '''//*[@id="glopopd_excel"]/span'''
element_get_excel = driver.find_element_by_xpath(xpath).click()
정상작동하는 것을 확인했으면 반복문을 사용해서 모든 데이터 다운받기
import time
from tqdm import tqdm_notebook #진행되는 과정을 보여줌
# 반복문을 이용하여 모든 구 엑셀파일 다운로드 진행
for gu in tqdm_notebook(gu_names):
element = driver.find_element_by_id('SIGUNGU_NM0')
element.send_keys(gu)
time.sleep(2)# 데이터 획득 위한 지연 시간
xpath ='''//*[@id="searRgSelect"]/span'''
element_sel_gu = driver.find_element_by_xpath(xpath).click()
time.sleep(1)
xpath = '''//*[@id="glopopd_excel"]/span'''
element_get_excel = driver.find_element_by_xpath(xpath).click()
time.sleep(1)
다운받은 후에는 파일의 위치를 옮겨주거나 파일 경로를 찾아야 함
# station_files 변수에 각 엑셀 파일의 경로와 이름을 리스트로 저장
stations_files = glob('지역*.xls')
stations_files
나는 현재 진행중인 주피터 노트북의 위치와 같은 위치에 저장함 그래서 경로 설정 없이 파일을 불러와서 저장
# concat 명령으로 합쳐본다.
tmp_raw = []
for file_name in stations_files:
tmp = pd.read_excel(file_name, header=2) #header함수를 이용해서 인덱스2인 행을 제일 윗 행으로 만듦
tmp_raw.append(tmp)
station_raw = pd.concat(tmp_raw)
header를 이용하여 필요없는 행을 날림
# 휘발유 데이터 저장.
stations = pd.DataFrame({'Oil_store': station_raw['상호'],
'주소': station_raw['주소'],
'가격': station_raw['휘발유'],
'셀프': station_raw['셀프여부'],
'상표': station_raw['상표']
})
stations.head()
딕셔너리 형태 사용해서 데이터프레임을 만듦
# 구 이름만 추출
stations['구'] = [eachAddress.split()[1] for eachAddress in stations['주소']]
stations.head()
주소에서 구를 기준으로 구만 출력해서 새로운 행 만들기
# unique() 이용해서 데이터 검사 수행
stations['구'].unique() #구에 있는 값을 하나 하나 뽑아내는것?
어떤 구가 있는지 확인
stations['가격'].unique() #가격에 '-'가 있음
가격에 있는 값들을 확인 '-' 값은 지워줘야함
#가격에 '-' 값만 추출
stations[stations['가격']=='-'].count() #17개 있음
# '-' 문자가 포함된 데이터 제외
stations = stations[stations['가격'] != '-']
# 가격 float 형 변환.
stations['가격'] = [float(value) for value in stations['가격']]
# reset_index 이용하여 index 재정의
stations.reset_index(inplace=True)
del stations['index']# 기존 인덱스 삭제
시각화
stations.boxplot(column='가격', by='셀프', figsize=(12,8))
plt.show()
그래프를 보면 셀프 주유소의 가격이 더 저렴하다는 것을 알 수 있음
plt.figure(figsize=(12,8))
sns.boxplot(x='상표', y='가격', hue='셀프', data=stations, palette='Set3')
plt.show()
sk에너지 주유소의 가격이 가장 비싸다는 것이 확인됨
plt.figure(figsize=(12,8))
sns.boxplot(x='상표', y='가격', data=stations, palette='Set3')
sns.swarmplot(x='상표', y='가격', data=stations, color='.6')
plt.show()
박스플롯과 함께 각 데이터들의 분포 확인
!pip install folium
!pip install googlemaps
#다운로드
import json
import folium
import googlemaps
# 이제 서울시에서 가장 주유 가격이 비싼 주유소
stations.sort_values(by='가격', ascending=False).head(10)
가격이 높은 상위 10개
import googlemaps
gmaps_key = 'AIzaSyDekfiVYSFscguylCGOYdtGTjwf0twUubE' # API설정할 때 얻은 key
gmaps = googlemaps.Client(key=gmaps_key)
# pivot_table을 이용해서 구별 가격 정보로 변경하고 가격 평균값 정리.
import numpy as np
gu_data = pd.pivot_table(stations, index=['구'], values=['가격'], aggfunc=np.mean)
gu_data.head()
구별로 가격의 평균을 구해서 저장
# 서울시 구별 정보에 대해 지도로 표현
geo_path = 'skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
map = folium.Map(location=[37.5502, 126.982], zoom_start=10.5,
tiles='Stamen Toner')
map.choropleth(geo_data = geo_str,
data = gu_data,
columns=[gu_data.index, '가격'],
fill_color='PuRd', #PuRd, YlGnBu
key_on='feature.id')
map
색깔이 진할수록 비싼 지역
# 주유 가격 상위 10개 주소 oil_price_top10 저장.
oil_price_top10 = stations.sort_values(by='가격', ascending=False).head(10)
#oil_price_top10
# 하위 10개 oil_price_bottom10 저장
oil_price_bottom10 = stations.sort_values(by='가격',
ascending=True).head(10)
#oil_price_bottom10
from tqdm import tqdm_notebook
lat = []
lng = []
for n in tqdm_notebook(oil_price_top10.index):
try:
tmp_add = str(oil_price_top10['주소'][n]).split('(')[0]
tmp_map = gmaps.geocode(tmp_add)
tmp_loc = tmp_map[0].get('geometry')
lat.append(tmp_loc['location']['lat'])
lng.append(tmp_loc['location']['lng'])
except:
lat.append(np.nan)
lng.append(np.nan)
print('Here is nan !')
oil_price_top10['lat']=lat
oil_price_top10['lng']=lng
#oil_price_top10
lat = []
lng = []
for n in tqdm_notebook(oil_price_bottom10.index):
try:
tmp_add = str(oil_price_bottom10['주소'][n]).split('(')[0] #괄호 제거
tmp_map = gmaps.geocode(tmp_add)
tmp_loc = tmp_map[0].get('geometry')
lat.append(tmp_loc['location']['lat'])
lng.append(tmp_loc['location']['lng'])
except:
lat.append(np.nan)
lng.append(np.nan)
print('Here is nan !')
oil_price_bottom10['lat']=lat
oil_price_bottom10['lng']=lng
#oil_price_bottom10
lat와 lug을 새로운 열 추가
map = folium.Map(location=[37.5202, 126.975], zoom_start=10.5)
for n in oil_price_top10.index:
if pd.notnull(oil_price_top10['lat'][n]):
folium.CircleMarker([oil_price_top10['lat'][n],
oil_price_top10['lng'][n]],
radius=15, color='#CD3181',
fill_color='#CD3181').add_to(map)
for n in oil_price_bottom10.index:
if pd.notnull(oil_price_bottom10['lat'][n]):
folium.CircleMarker([oil_price_bottom10['lat'][n],
oil_price_bottom10['lng'][n]],
radius=15, color='#3186cc',
fill_color='#3186cc').add_to(map)
map
지도에 원으로 나타내기
'데이터 청년 캠퍼스(경남대학교) > 수업' 카테고리의 다른 글
2021-07-09 (0) | 2021.07.09 |
---|---|
2021 - 07 - 02 (0) | 2021.07.02 |
2021-07-01 (1) (0) | 2021.07.01 |
2021-06-29 (0) | 2021.07.01 |
2021-06-28 (0) | 2021.07.01 |