2016-11-16 2 views
0

Я пытаюсь получить некоторые результаты голосования на веб-сайте politco, используя rvest.Использование rvest для захвата данных Нет совпадений

http://www.politico.com/2016-election/results/map/president/wisconsin/

Я не мог вытащить все данные на странице сразу, так что я пошел для подхода уездных. В каждом графстве есть уникальный селектор css (например, графство Адамс: «#countyAdams .results-table»). Поэтому я схватил все имена графств из других мест и установил быстрый цикл (да, я знаю, что петли - это плохая практика в R, но я ожидал, что этот метод займет у меня около 3 минут).

захватить URL

wiscoSixteen <- read_html("http://www.politico.com/2016-election/results/map/president/wisconsin") 

Создайте пустой data.frame (и нет, я не предопределить столбцы)

stateDf <- NULL 

Получить список стран (это не полный, но, чтобы добраться до точки процедуры перерывы нам не нужны все 70 округов)

wiscoCounties <- c("Adams", "Ashland", "Barron", "Bayfield", "Brown", "Buffalo", "Burnett", "Calumet", "Chippewa", "Clark", "Columbia", "Crawford", "Dane", "Dodge", "Door", "Douglas", "Dunn", "Eau Claire", "Florence", "Fond du Lac", "Forest", "Grant", "Green", "Green Lake", "Iowa", "Iron", "Jackson", "Jefferson", "Juneau") 

My «для» петли:

for (i in 1:length(wiscoCounties)){ 

    #Pull out the i'th county name and paste it in a string 
    wiscoResult <- wiscoSixteen %>% html_node(paste("#county"," .results-table", sep=wiscoCounties[i])) %>% html_table() 

    #add a column for the county name so I can ID later 
    wiscoResult[,4] <- wiscoCounties[i] 

    #then rbind 
    stateDf <- rbind(stateDf, wiscoResult) 
} 

Когда он проходит через 10-й округ, он останавливается и возвращает «Ошибка: нет совпадений».

Невозможно найти что-либо уникальное в «Колумбии», 11-м округе. В пропасть за то, что происходит. Я уверен, что это что-то глупое, как обычно. Любая помощь приветствуется.

+0

FWIW, петли в порядке. Вы можете прочитать [R inferno] (http://www.burns-stat.com/pages/Tutor/R_inferno.pdf), чтобы узнать, почему. –

ответ

3

Итак, почему бы не просто использовать запросы XHR, что в конечном итоге заполнения этих таблиц (я вроде удивлен, что вы получаете какие-либо данные на всех из них, так как они получают генерируется из отдельного запроса данных):

library(httr) 
library(stringi) 
library(purrr) 
library(dplyr) 

res <- GET("http://s3.amazonaws.com/origin-east-elections.politico.com/mapdata/2016/WI_20161108.xml") 
dat <- readLines(textConnection(content(res, as="text"))) 

stri_split_fixed(dat[2], "|")[[1]] %>% 
    stri_replace_last_fixed(";", "") %>% 
    stri_split_fixed(";", 3) %>% 
    map_df(~setNames(as.list(.), c("rep_id", "first", "last"))) -> candidates 

dat[stri_detect_regex(dat, "^WI;P;G")] %>% 
    stri_replace_first_regex("^WI;P;G;", "") %>% 
    map_df(function(x) { 

    county_results <- stri_split_fixed(x, "||", 2)[[1]] 

    stri_replace_last_fixed(county_results[1], ";;", "") %>% 
     stri_split_fixed(";") %>% 
     map_df(~setNames(as.list(.), c("fips", "name", "x1", "reporting", "x2", "x3", "x4"))) -> county_prefix 

    stri_split_fixed(county_results[2], "|")[[1]] %>% 
     stri_split_fixed(";") %>% 
     map_df(~setNames(as.list(.), c("rep_id", "party", "count", "pct", "x5", "x6", "x7", "x8", "candidate_idx"))) %>% 
     left_join(candidates, by="rep_id") -> df 

    df$fips <- county_prefix$fips 
    df$name <- county_prefix$name 
    df$reporting <- county_prefix$reporting 

    select(df, -starts_with("x")) 

    }) -> results 

Казалось бы, полные данные:

glimpse(results) 
## Observations: 511 
## Variables: 10 
## $ rep_id  <chr> "WI270631108", "WI270621108", "WI270691108", "WI270711108", "WI270701108", "WI270731108", "WI270721108",... 
## $ party   <chr> "Dem", "GOP", "Lib", "CST", "ADP", "WW", "Grn", "Dem", "GOP", "Lib", "CST", "ADP", "WW", "Grn", "Dem", "... 
## $ count   <chr> "1382210", "1409467", "106442", "12179", "1561", "1781", "30980", "3780", "5983", "207", "44", "4", "9",... 
## $ pct   <chr> "46.9", "47.9", "3.6", "0.4", "0.1", "0.1", "1.1", "37.4", "59.2", "2.0", "0.4", "0.0", "0.1", "0.8", "5... 
## $ candidate_idx <chr> "1", "2", "3", "4", "5", "6", "7", "1", "2", "3", "4", "5", "6", "7", "1", "2", "3", "4", "5", "6", "7",... 
## $ first   <chr> "Clinton", "Trump", "Johnson", "Castle", "De La Fuente", "Moorehead", "Stein", "Clinton", "Trump", "John... 
## $ last   <chr> "Hillary", "Donald", "Gary", "Darrell", "Rocky", "Monica", "Jill", "Hillary", "Donald", "Gary", "Darrell... 
## $ fips   <chr> "0", "0", "0", "0", "0", "0", "0", "55001", "55001", "55001", "55001", "55001", "55001", "55001", "55003... 
## $ name   <chr> "Wisconsin", "Wisconsin", "Wisconsin", "Wisconsin", "Wisconsin", "Wisconsin", "Wisconsin", "Adams", "Ada... 
## $ reporting  <chr> "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.0", "100.... 

Несмотря на ".xml" расширение на URL, это не данные XML. Я также не знаю, каковы некоторые из столбцов, но вы можете вникать в это. Кроме того, есть целый другой раздел данных:

WI;S;G;0;Wisconsin;X;100.0;X;;50885;;||WI269201108;Dem;1380496;46.8;;X;;;1|WI267231108;GOP;1479262;50.2;X;X;X;;2|WI270541108;Lib;87291;3.0;;X;;;3 
WI;S;G;55001;Adams;X;100.0;X;;50885;;||WI269201108;Dem;4093;41.2;;X;;;1|WI267231108;GOP;5346;53.9;X;X;X;;2|WI270541108;Lib;486;4.9;;X;;;3 
WI;S;G;55003;Ashland;X;100.0;X;;50885;;||WI269201108;Dem;4349;55.1;;X;;;1|WI267231108;GOP;3337;42.2;X;X;X;;2|WI270541108;Lib;214;2.7;;X;;;3 
WI;S;G;55005;Barron;X;100.0;X;;50885;;||WI269201108;Dem;8691;38.8;;X;;;1|WI267231108;GOP;12863;57.4;X;X;X;;2|WI270541108;Lib;853;3.8;;X;;;3 
WI;S;G;55007;Bayfield;X;100.0;X;;50885;;||WI269201108;Dem;5161;54.6;;X;;;1|WI267231108;GOP;4022;42.6;X;X;X;;2|WI270541108;Lib;263;2.8;;X;;;3 
WI;S;G;55009;Brown;X;100.0;X;;50885;;||WI269201108;Dem;51004;40.0;;X;;;1|WI267231108;GOP;71750;56.3;X;X;X;;2|WI270541108;Lib;4615;3.6;;X;;;3 
WI;S;G;55011;Buffalo;X;100.0;X;;50885;;||WI269201108;Dem;2746;39.9;;X;;;1|WI267231108;GOP;3850;56.0;X;X;X;;2|WI270541108;Lib;285;4.1;;X;;;3 
WI;S;G;55013;Burnett;X;100.0;X;;50885;;||WI269201108;Dem;3143;37.4;;X;;;1|WI267231108;GOP;4998;59.5;X;X;X;;2|WI270541108;Lib;258;3.1;;X;;;3 

, который, очевидно, означает, что что-то для этой страницы (это своего рода очевидна, но я так устал от выборов, что я своего рода сделал с данными), и вы может обрабатываться аналогично тому, что указано выше.

+0

Спасибо. Во-первых, я не эксперт с веб-страницами, о которых я никогда бы не узнал, это был запрос XHR. Во-вторых, URL-адрес в первой строке кода после вызова пакетов ... где вы его копали. Я чувствую, что это то, что я использовал, чтобы знать, как это сделать, но не смог найти ничего в исходном коде. Это очень поможет, поскольку я извлекаю данные из нескольких штатов. – noLongerRandom

+0

Использование Chrome (у других браузеров это тоже, но менее открыто). Осмотрите страницу, а затем обновите ее. Затем на вкладке «Сеть» окна инспектора нажмите «XHR» в строке под вкладками. Вы увидите это там. Я подозреваю, что этот код будет работать для всех состояний (с некоторыми улучшениями для сокращений состояний), поскольку у них есть внешний интерфейс javascript, который его читает, и поэтому он должен быть однородным. Опубликуйте добавление, если нет.Это конкретное пререкание было любопытным, особенно учитывая искаженный ум разработчиков, которые создали этот формат :-) – hrbrmstr

+0

Я бы также запустил 'readr :: type_convert()' в фрейме данных результатов, чтобы получить соответствующие типы. – hrbrmstr

Смежные вопросы