선관위 웹사이트에서 데이터를 다운로드 받습니다.
선관위 웹사이트 에서 2021년 서울/부산 시장 재보궐선거 개표결과를 공지하여 데이터를 제공하고 있다.
electionId
# 0. 환경설정 -----
library(tidyverse)
library(rvest)
library(httr)
# 1. 데이터 받아오기 -----
## 1.1 POST() 함수를 사용하여 개표 결과를 수집합니다.
resp <- POST(
url = 'http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml',
encode = 'form',
body = list(
electionId = "0020210407",
requestURI = "/WEB-INF/jsp/electioninfo/0020210407/vc/vccp08.jsp",
topMenuId = "VC",
secondMenuId = "VCCP08",
menuId = "VCCP08",
statementId = "VCCP08_#3",
electionCode = "3",
cityCode = "1100",
sggCityCode = "-1",
townCodeFromSgg = "-1",
townCode = "1101",
checkCityCode = "-1",
x = "17",
y = "9"
)
)
vote_raw <- content(x=resp, as = 'text') %>%
read_html() %>%
html_node(xpath = '//*[@id="table01"]') %>%
html_table(fill=TRUE) %>%
janitor::clean_names() %>%
as_tibble()
vote_tbl <- vote_raw %>%
set_names(c("읍면동명", "투표구명", "선거인수", "투표수", "민주당", "국힘당", glue::glue("후보{1:10}"), "계", "무효", "기권")) %>%
select(읍면동명, 투표구명, 선거인수, 투표수, 민주당, 국힘당, 기권) %>%
slice(2:n()) %>%
mutate(읍면동명 = ifelse(읍면동명 == "", NA, 읍면동명)) %>%
mutate(읍면동명 = zoo::na.locf(읍면동명)) %>%
filter(읍면동명 != "합계",
투표구명 != "소계") %>%
mutate_at(c("선거인수", "투표수", "민주당", "국힘당", "기권"), parse_number) %>%
mutate(구명 = "종로구") %>%
relocate(구명, before = "읍면동명")
sum(vote_tbl$투표수) == 78852
[1] TRUE
get_vote <- function(gu_code) {
resp <- POST(
url = 'http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml',
encode = 'form',
body = list(
electionId = "0020210407",
requestURI = "/WEB-INF/jsp/electioninfo/0020210407/vc/vccp08.jsp",
topMenuId = "VC",
secondMenuId = "VCCP08",
menuId = "VCCP08",
statementId = "VCCP08_#3",
electionCode = "3",
cityCode = "1100",
sggCityCode = "-1",
townCodeFromSgg = "-1",
townCode = gu_code,
checkCityCode = "-1",
x = "17",
y = "9"
)
)
vote_raw <- content(x=resp, as = 'text') %>%
read_html() %>%
html_node(xpath = '//*[@id="table01"]') %>%
html_table(fill=TRUE) %>%
janitor::clean_names() %>%
as_tibble()
vote_tbl <- vote_raw %>%
set_names(c("읍면동명", "투표구명", "선거인수", "투표수", "민주당", "국힘당", glue::glue("후보{1:10}"), "계", "무효", "기권")) %>%
select(읍면동명, 투표구명, 선거인수, 투표수, 민주당, 국힘당, 기권) %>%
slice(2:n()) %>%
mutate(읍면동명 = ifelse(읍면동명 == "", NA, 읍면동명)) %>%
mutate(읍면동명 = zoo::na.locf(읍면동명)) %>%
filter(읍면동명 != "합계",
투표구명 != "소계") %>%
mutate_at(c("선거인수", "투표수", "민주당", "국힘당", "기권"), parse_number) %>%
mutate(구코드 = gu_code) %>%
relocate(구코드, .before = "읍면동명")
vote_tbl
}
get_vote("1101")
# A tibble: 63 x 8
구코드 읍면동명 투표구명 선거인수 투표수 민주당 국힘당 기권
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1101 거소투표 "" 910 870 235 530 40
2 1101 관외사전투표… "" 4962 4961 2218 2508 1
3 1101 청운효자동 "관내사전투표"… 2318 2318 1296 952 0
4 1101 청운효자동 "청운효자동제1투"… 2428 1187 404 732 1241
5 1101 청운효자동 "청운효자동제2투"… 2408 1157 440 661 1251
6 1101 청운효자동 "청운효자동제3투"… 2503 1274 554 638 1229
7 1101 사직동 "관내사전투표"… 1737 1736 863 808 1
8 1101 사직동 "사직동제1투"… 2305 919 354 530 1386
9 1101 사직동 "사직동제2투"… 4191 2267 527 1666 1924
10 1101 삼청동 "관내사전투표"… 505 505 248 240 0
# … with 53 more rows
gu_code <- glue::glue("11{str_pad(1:25, width = 2, side='left', pad =0)}")
gu_name_tbl <- tribble(~"구코드", ~"구명",
"1101", "종로구",
"1102", "중구",
"1103", "용산구",
"1104", "성동구",
"1105", "광진구",
"1106", "동대문구",
"1107", "중랑구",
"1108", "성북구",
"1109", "강북구",
"1110", "도봉구",
"1111", "노원구",
"1112", "은평구",
"1113", "서대문구",
"1114", "마포구",
"1115", "양천구",
"1116", "강서구",
"1117", "구로구",
"1118", "금천구",
"1119", "영등포구",
"1120", "동작구",
"1121", "관악구",
"1122", "서초구",
"1123", "강남구",
"1124", "송파구",
"1125", "강동구")
# seoul_raw <- map_df(gu_code, get_vote)
#
# seoul_tbl <- seoul_raw %>%
# left_join(gu_name_tbl) %>%
# select(-구코드) %>%
# relocate(구명, .before = "읍면동명")
#
# seoul_tbl %>%
# write_rds("data/seoul_tbl.rds")
seoul_tbl <- read_rds("data/seoul_tbl.rds")
seoul_tbl %>%
reactable::reactable()
# 1. 데이터 받아오기 -----
## 1.1 POST() 함수를 사용하여 개표 결과를 수집합니다.
pusan_resp <- POST(
url = 'http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml',
encode = 'form',
body = list(
electionId = "0020210407",
requestURI = "/WEB-INF/jsp/electioninfo/0020210407/vc/vccp08.jsp",
topMenuId = "VC",
secondMenuId = "VCCP08",
menuId = "VCCP08",
statementId = "VCCP08_#3",
electionCode = "3",
cityCode = "2600",
sggCityCode = "-1",
townCodeFromSgg = "-1",
townCode = "2601",
checkCityCode = "-1",
x = "17",
y = "9"
)
)
busan_vote_raw <- content(x = pusan_resp, as = 'text') %>%
read_html() %>%
html_node(xpath = '//*[@id="table01"]') %>%
html_table(fill=TRUE) %>%
janitor::clean_names() %>%
as_tibble()
busan_vote_tbl <- busan_vote_raw %>%
set_names(c("읍면동명", "투표구명", "선거인수", "투표수", "민주당", "국힘당", glue::glue("후보{1:4}"), "계", "무효", "기권")) %>%
select(읍면동명, 투표구명, 선거인수, 투표수, 민주당, 국힘당, 기권) %>%
slice(2:n()) %>%
mutate(읍면동명 = ifelse(읍면동명 == "", NA, 읍면동명)) %>%
mutate(읍면동명 = zoo::na.locf(읍면동명)) %>%
filter(읍면동명 != "합계",
투표구명 != "소계") %>%
mutate_at(c("선거인수", "투표수", "민주당", "국힘당", "기권"), parse_number) %>%
mutate(구명 = "중구") %>%
relocate(구명, before = "읍면동명")
busan_vote_tbl
# A tibble: 34 x 8
구명 before 투표구명 선거인수 투표수 민주당 국힘당 기권
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 중구 거소투표 "" 208 199 68 91 9
2 중구 관외사전투표… "" 1332 1332 559 710 0
3 중구 중앙동 "관내사전투표"… 334 334 130 187 0
4 중구 중앙동 "중앙동제1투" 1126 308 103 187 818
5 중구 중앙동 "중앙동제2투" 798 263 87 159 535
6 중구 동광동 "관내사전투표"… 619 619 236 363 0
7 중구 동광동 "동광동제1투" 1126 349 118 220 777
8 중구 동광동 "동광동제2투" 986 395 121 258 591
9 중구 대청동 "관내사전투표"… 914 914 371 524 0
10 중구 대청동 "대청동제1투" 2017 755 241 485 1262
# … with 24 more rows
get_busan_vote <- function(gu_code) {
resp <- POST(
url = 'http://info.nec.go.kr/electioninfo/electionInfo_report.xhtml',
encode = 'form',
body = list(
electionId = "0020210407",
requestURI = "/WEB-INF/jsp/electioninfo/0020210407/vc/vccp08.jsp",
topMenuId = "VC",
secondMenuId = "VCCP08",
menuId = "VCCP08",
statementId = "VCCP08_#3",
electionCode = "3",
cityCode = "2600",
sggCityCode = "-1",
townCodeFromSgg = "-1",
townCode = gu_code,
checkCityCode = "-1",
x = "17",
y = "9"
)
)
vote_raw <- content(x=resp, as = 'text') %>%
read_html() %>%
html_node(xpath = '//*[@id="table01"]') %>%
html_table(fill=TRUE) %>%
janitor::clean_names() %>%
as_tibble()
vote_tbl <- vote_raw %>%
set_names(c("읍면동명", "투표구명", "선거인수", "투표수", "민주당", "국힘당", glue::glue("후보{1:4}"), "계", "무효", "기권")) %>%
select(읍면동명, 투표구명, 선거인수, 투표수, 민주당, 국힘당, 기권) %>%
slice(2:n()) %>%
mutate(읍면동명 = ifelse(읍면동명 == "", NA, 읍면동명)) %>%
mutate(읍면동명 = zoo::na.locf(읍면동명)) %>%
filter(읍면동명 != "합계",
투표구명 != "소계") %>%
mutate_at(c("선거인수", "투표수", "민주당", "국힘당", "기권"), parse_number) %>%
mutate(구코드 = gu_code) %>%
relocate(구코드, .before = "읍면동명")
vote_tbl
}
get_busan_vote("2601")
# A tibble: 34 x 8
구코드 읍면동명 투표구명 선거인수 투표수 민주당 국힘당 기권
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2601 거소투표 "" 208 199 68 91 9
2 2601 관외사전투표… "" 1332 1332 559 710 0
3 2601 중앙동 "관내사전투표"… 334 334 130 187 0
4 2601 중앙동 "중앙동제1투"… 1126 308 103 187 818
5 2601 중앙동 "중앙동제2투"… 798 263 87 159 535
6 2601 동광동 "관내사전투표"… 619 619 236 363 0
7 2601 동광동 "동광동제1투"… 1126 349 118 220 777
8 2601 동광동 "동광동제2투"… 986 395 121 258 591
9 2601 대청동 "관내사전투표"… 914 914 371 524 0
10 2601 대청동 "대청동제1투"… 2017 755 241 485 1262
# … with 24 more rows
gu_busan_code <- glue::glue("26{str_pad(1:16, width = 2, side='left', pad =0)}")
gu_name_busan_tbl <- tribble(~"구코드", ~"구명",
"2601", "중구",
"2602", "서구",
"2603", "동구",
"2604", "영도구",
"2605", "부산진구",
"2606", "동래구",
"2607", "남구",
"2608", "북구",
"2609", "해운대구",
"2610", "기장군",
"2611", "사하구",
"2612", "금정구",
"2613", "강서구",
"2614", "연제구",
"2615", "수영구",
"2616", "사상구")
# busan_raw <- map_df(gu_busan_code, get_busan_vote)
#
# busan_tbl <- busan_raw %>%
# left_join(gu_name_busan_tbl) %>%
# select(-구코드) %>%
# relocate(구명, .before = "읍면동명")
#
# busan_tbl %>%
# write_rds("data/busan_tbl.rds")
busan_tbl <- read_rds("data/busan_tbl.rds")
busan_tbl %>%
reactable::reactable()