본문 바로가기
  • 紹睿: 자유롭고 더불어 사는 가치있는 삶
Study/파이썬으로 데이터 주무르기

[19대 선거] Selenium을 이용한 19대 선거 데이터 크롤링

by 징여 2018. 7. 16.
반응형

 

 

Selenium을 이용한 선거구 데이터 크롤링¶

(사실 그냥 다운로드하면 편하다)

In [1]:
import pandas as pd
import numpy as np

import platform
import matplotlib.pyplot as plt
%matplotlib inline
 

폰트 설정¶

In [2]:
from matplotlib import font_manager, rc

rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
 

방법¶

  1. 홈페이지에 접근(http://info.nec.go.kr/)
  2. 역대선거 클릭
  3. 투개표 클릭
  4. 개표현황 클릭
  5. 대통령 선거 클릭
  6. 정보 가져오기
In [3]:
from selenium import webdriver
import time
In [4]:
driver = webdriver.Chrome('./chromedriver')
driver.get('http://info.nec.go.kr')
 

1. 홈페이지 접근¶

In [5]:
driver.switch_to_default_content()
driver.switch_to_frame('main')
 

2. 역대선거 클릭¶

In [6]:
driver.find_element_by_class_name("eright").click()
 

3. 투개표 클릭¶

In [7]:
driver.find_element_by_xpath("""//*[@id="presubmu"]/li[3]/a""").click()
 

4. 개표현황 클릭¶

In [8]:
driver.find_element_by_xpath("""//*[@id="header"]/div[4]/ul/li[4]/a""").click()
 

5. 대통령선거 클릭¶

In [9]:
driver.find_element_by_xpath("""//*[@id="electionType1"]""").click()
 

6. 몇대 선거를 선택할지 및 선거 시도¶

In [10]:
select_list_raw = driver.find_element_by_xpath("""//*[@id="electionName"]""")
select_list=select_list_raw.find_elements_by_tag_name("option")
select_names = [option.text for option in select_list]
select_names = select_names[1:]
print(select_names)
 
['제19대', '제18대', '제17대', '제16대', '제15대', '제14대', '제13대', '제12대', '제11대', '제10대', '제9대', '제8대', '제7대', '제6대', '제5대', '제4대', '제3대', '제2대', '제1대']
 

제 19대를 클릭해주자

In [12]:
code_list_raw = driver.find_element_by_xpath("""//*[@id="electionCode"]""")
code_list=code_list_raw.find_elements_by_tag_name("option")
code_names = [option.text for option in code_list]
code_names = code_names[1:]
code_names
Out[12]:
['대통령선거']
 

대통령 선거도 클릭해주자

In [14]:
city_list_raw = driver.find_element_by_xpath("""//*[@id="cityCode"]""")
city_list=city_list_raw.find_elements_by_tag_name("option")
city_names = [option.text for option in city_list]
city_names = city_names[2:]
print(city_names)
 
['서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시', '울산광역시', '세종특별자치시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도', '경상북도', '경상남도', '제주특별자치도']
 

서울특별시도 클릭해주자!

 

7. 검색 버튼 클릭!¶

In [16]:
driver.find_element_by_xpath("""//*[@id="searchBtn"]""").click()
 

그럼 우리는 chromdriver에서 서울특별시의 정보가 뜨는 것을 볼수 있다

 

BeautifulSoup을 이용하여 selenium으로 접근한 페이지를 가져오자!¶

In [19]:
from bs4 import BeautifulSoup
 

1. 해당page의 내용을 긁어오자¶

나는 투표수, 문재인, 홍준표, 안철수 까지만 긁어올 것이야

In [21]:
def get_vote(n):
    # selenium 페이지를 beautifulsoup으로 불러오기
    name = n
    html = driver.page_source
    soup = BeautifulSoup(html, 'lxml')
    
    # tmp에는 투표값들이 들어가있고,
    # gu에는 구값들이 들어가 있다.
    tmp = soup.find_all('td', 'alignR')
    gu = soup.find_all('td', 'alignL')
    gu_names = [tmp_val.get_text() for tmp_val in gu[1:]]

    # 줄에 해당하는 투표수, 문재인, 홍준표, 안철수가 해당하는 table수를 계산해서 그 값들만 뽑아 [list]형식으로 만들고
    # 그값을 key = gu, value = tmp_list로 하여 dictionary에 넣어주자
    tmp_list = []
    for i in range(19, len(tmp), 18):
        tmp_values = [(tmp_val.get_text().replace(",", '')) for tmp_val in tmp[i:i+4]]
        tmp_list.append(tmp_values)
    tmp_list = tmp_list[:-1]
    gu_dict = {}
    for i in range(len(tmp_list)):
        name = gu_names[i]
        items = tmp_list[i]
        gu_dict[name] = items
    gu_dict
    
    # dictionary를 DataFrame으로 바꿔주고, 컬럼명을 변경해준다.
    result =pd.DataFrame.from_dict(gu_dict).T
    result.columns = ['pop', 'moon', 'hong', 'ahn']
    
    # 모든 광역시에 대하여 가져올것이기 때문에, 광역시도 컬럼을 만들어 해당 시도를 입력하준다.
    result['광역시도'] = n
    result.reset_index(inplace=True)
    result.rename(index=str, columns={"index": "시군"}, inplace = True)
    
    return result
 

2. 이제 cityCode마다 돌면서, 값을 다 긁어와주자!¶

In [22]:
for city in city_names:
    element = driver.find_element_by_id("cityCode")
    element.send_keys(city)
    driver.find_element_by_xpath("""//*[@id="searchBtn"]""").click()
    tmp = get_vote(city)
    
    if city ==city_names[0]:
        result = tmp
    else:
        result = result.append(tmp)

result
Out[22]:
  시군 pop moon hong ahn 광역시도
0 종로구 102566 42512(41.59) 22325(21.84) 22313(21.83) 서울특별시
1 중구 82852 34062(41.23) 17901(21.67) 19372(23.45) 서울특별시
2 용산구 148157 58081(39.33) 35230(23.85) 32109(21.74) 서울특별시
3 성동구 203175 86686(42.80) 40566(20.03) 45674(22.55) 서울특별시
4 광진구 240030 105512(44.10) 46368(19.38) 52824(22.08) 서울특별시
5 동대문구 236092 98958(42.06) 51631(21.94) 53359(22.68) 서울특별시
6 중랑구 265706 111450(42.09) 56545(21.35) 62778(23.71) 서울특별시
7 성북구 295866 129263(43.82) 57584(19.52) 66518(22.55) 서울특별시
8 강북구 210614 89645(42.70) 42268(20.13) 51669(24.61) 서울특별시
9 도봉구 229233 94898(41.55) 47461(20.78) 55600(24.34) 서울특별시
10 노원구 374213 158167(42.41) 67590(18.12) 96325(25.83) 서울특별시
11 은평구 317275 140180(44.34) 60109(19.01) 72582(22.96) 서울특별시
12 서대문구 212076 93768(44.36) 40513(19.16) 46237(21.87) 서울특별시
13 마포구 256992 117336(45.79) 46547(18.16) 52545(20.50) 서울특별시
14 양천구 310886 133853(43.18) 60814(19.62) 71816(23.17) 서울특별시
15 강서구 397108 175882(44.43) 76601(19.35) 88128(22.26) 서울특별시
16 구로구 278805 121077(43.59) 59194(21.31) 61734(22.22) 서울특별시
17 금천구 155010 67423(43.65) 31106(20.13) 36695(23.75) 서울특별시
18 영등포구 248833 105834(42.67) 53615(21.61) 53994(21.77) 서울특별시
19 동작구 276685 121722(44.12) 54431(19.73) 60305(21.86) 서울특별시
20 관악구 351240 159854(45.67) 59914(17.11) 79495(22.71) 서울특별시
21 서초구 292916 106416(36.43) 74891(25.63) 63977(21.90) 서울특별시
22 강남구 365642 128927(35.36) 97639(26.78) 80201(21.99) 서울특별시
23 송파구 441198 177328(40.30) 98549(22.40) 99018(22.50) 서울특별시
24 강동구 297476 122511(41.31) 65893(22.22) 67499(22.76) 서울특별시
0 중구 28604 9918(34.78) 10684(37.47) 4675(16.39) 부산광역시
1 서구 71446 24522(34.46) 26360(37.04) 11868(16.68) 부산광역시
2 동구 58304 19606(33.75) 22188(38.20) 9815(16.89) 부산광역시
3 영도구 78013 30094(38.75) 25345(32.63) 13082(16.84) 부산광역시
4 부산진구 246124 95042(38.76) 79545(32.44) 40636(16.57) 부산광역시
... ... ... ... ... ... ...
18 의성군 37855 5365(14.27) 23790(63.30) 4767(12.68) 경상북도
19 청송군 18418 3218(17.58) 10669(58.29) 2387(13.04) 경상북도
20 영양군 12048 2281(19.08) 6554(54.84) 1701(14.23) 경상북도
21 영덕군 26125 3786(14.61) 16314(62.96) 3231(12.47) 경상북도
22 봉화군 22947 4209(18.47) 12536(55.02) 3370(14.79) 경상북도
23 울진군 32568 6972(21.55) 16867(52.14) 4476(13.83) 경상북도
0 창원시의창구 164047 60757(37.22) 56887(34.85) 22830(13.98) 경상남도
1 창원시성산구 153327 63717(41.74) 42052(27.54) 22923(15.01) 경상남도
2 창원시마산합포구 119281 35592(29.99) 54488(45.91) 14686(12.37) 경상남도
3 창원시마산회원구 136757 45014(33.07) 56340(41.39) 17744(13.03) 경상남도
4 창원시진해구 114779 41249(36.11) 40049(35.06) 17435(15.26) 경상남도
5 진주시 222813 73929(33.35) 93751(42.30) 26687(12.04) 경상남도
6 통영시 82855 25477(30.94) 36128(43.87) 10738(13.04) 경상남도
7 고성군 34603 9848(28.67) 16797(48.91) 4104(11.95) 경상남도
8 사천시 71555 22370(31.47) 32475(45.69) 8350(11.74) 경상남도
9 김해시 318253 147972(46.72) 82880(26.17) 45126(14.24) 경상남도
10 밀양시 70687 20842(29.68) 32394(46.14) 9073(12.92) 경상남도
11 거제시 150230 68291(45.71) 38775(25.95) 20359(13.62) 경상남도
12 의령군 19258 5115(26.85) 10134(53.21) 1984(10.41) 경상남도
13 함안군 43866 13597(31.21) 19809(45.48) 5399(12.39) 경상남도
14 창녕군 42878 10310(24.28) 24464(57.63) 3877(9.13) 경상남도
15 양산시 199835 83412(41.94) 58811(29.57) 30945(15.55) 경상남도
16 하동군 34324 11211(33.00) 14864(43.76) 4150(12.21) 경상남도
17 남해군 30208 8680(29.00) 14166(47.33) 3906(13.05) 경상남도
18 함양군 26640 7388(28.02) 13008(49.34) 3203(12.14) 경상남도
19 산청군 24513 6561(27.00) 12544(51.63) 2753(11.33) 경상남도
20 거창군 41325 11256(27.48) 19976(48.78) 4923(12.02) 경상남도
21 합천군 33021 7143(21.83) 19699(60.22) 3077(9.40) 경상남도
0 제주시 273163 125717(46.25) 48027(17.67) 55971(20.59) 제주특별자치도
1 서귀포시 101296 43776(43.50) 20036(19.91) 21890(21.75) 제주특별자치도

250 rows × 6 columns

 

3. 마지막으로 저장! 끗¶

In [23]:
result.to_csv('./data/election_result.csv', encoding='utf-8', sep=',')

 

 

반응형

댓글