2017-02-17 10 views
-1

Мне удалось очистить эту страницу википедии Oscars Nominations и извлечь таблицу под «Номинанты». Я могу получить таблицу с помощью кода ниже:Веб-скребок Википедия - манипуляция строк

wiki <- "https://en.wikipedia.org/wiki/89th_Academy_Awards" 
text <- wiki %>% 
     read_html() %>% 
     html_nodes('//*[@id="mw-content-text"]/table[3]') %>% 
     html_table() 

, который выводит «список» как имя «текст»

test <- data.frame(one=unlist(text), stringsAsFactors=F) 
row.names(test) <- NULL 
test <- test[-16,] 
nw_lst <- strsplit(test, "\n") 

я стараюсь поместить результаты в ЦФ, а затем удалить бесполезная строка, а затем «strsplit» в строке break regex '\ n' в 'nw_lst', которая выводит другой список, но намного более чистый с 23 элементами, который соответствует каждой номинации на оскар с названиями, перечисленными ниже. Затем я хочу разобрать список на 2 df, один для номинации «Лучшая картинка» и второй df с другими номинациями.

oscr.bp <- data.frame(Best.Picture=unlist(nw_lst[[1]]), stringsAsFactors=F) 
oscr.bp <- as.data.frame(oscr.bp[-1,], stringsAsFactors=F) 
colnames(oscr.bp) <- c("Best.Picture") 

Итак, вот моя проблема, как только я отделяю кандидатуры, я хотел бы очистить текст. Проблема в том, что по какой-то причине ничто в пакете «stringr» не удаляет весь ненужный текст, кроме названия фильма.

str_replace_all(oscr.bp$Best.Picture,pattern = "\n", replacement = " ") 
str_replace_all(oscr.bp$Best.Picture,pattern = "[\\^]", replacement = " ") 
str_replace_all(oscr.bp$Best.Picture,pattern = "\"", replacement = " ") 
str_replace_all(oscr.bp$Best.Picture,pattern = "\\s+", replacement = " ") 
str_trim(oscr.bp$Best.Picture,side = "both") 

Но когда я проверить структуру ЦФ в моем окружении и нажмите синюю стрелку, чтобы увидеть векторные классы и наведите курсор на CHR вектор, но он имеет странные формы в пределах вектора символов и имеет этот |__truncated__ внутри в строка, но не отображается при проверке строки в консоли.

Я просто хочу знать, как лучше всего чистить эти строки, или другой способ получить только названия названий для каждой номинации внутри HTML-узлов под <ul> и <li> parse? Не знаю много о базовых значениях кода HTML, кроме как просматривать исходный код и находить то, что мне нужно, с помощью гаджета селектора.

+0

«имеет странные формы в пределах вектора символов» - это, скорее всего, проблема кодирования (см 'Encoding '). Вы пробовали функции анализа gtml в пакете 'XML'? – Jean

ответ

2

Другой подход заключается в целевой каждого отдельного <td> используют метаданные через:

library(rvest) 
library(tidyverse) 

pg <- read_html("https://en.wikipedia.org/wiki/89th_Academy_Awards") 

html_nodes(pg, xpath=".//h2[span/@id = 'Nominees']/following-sibling::table[1]") %>% 
    html_nodes("td") %>% 
    map_df(function(x) { 
    category <- html_nodes(x, "div") %>% html_text() 
    html_nodes(x, "li") %>% 
     map_df(function(y) { 
     html_nodes(y, "a") %>% html_attr("title") -> tmp 
     movie <- tmp[1] 
     nominee <- tmp[-1] 
     data_frame(movie=rep(movie, length(nominee)), nominee) 
     }) %>% 
     mutate(category = category) 
    }) %>% 
    select(category, movie, nominee) 
## # A tibble: 236 × 3 
##  category   movie   nominee 
##   <chr>   <chr>    <chr> 
## 1 Best Picture Arrival (film)  Shawn Levy 
## 2 Best Picture Arrival (film)  David Linde 
## 3 Best Picture Fences (film)  Scott Rudin 
## 4 Best Picture Fences (film) Denzel Washington 
## 5 Best Picture Fences (film)  Todd Black 
## 6 Best Picture Hacksaw Ridge  Bill Mechanic 
## 7 Best Picture Hacksaw Ridge  David Permut 
## 8 Best Picture Hidden Figures Donna Gigliotti 
## 9 Best Picture Hidden Figures  Peter Chernin 
## 10 Best Picture Hidden Figures  Jenno Topping 
## # ... with 226 more rows 
+0

Это именно то, чего я пытался достичь. Как вы получили этот xpath в начале вашего кода? вы использовали инструмент или просто просмотрели HTML-код? – mikeymike

+0

Просто взглянув на код. XPath & У меня давние отношения любви/ненависти. – hrbrmstr

+0

Это отлично подходит для Best Picture, но если мы посмотрим на Best Director, например, имя режиссера на первом месте. Так что в конечном итоге колонка «фильм» содержит имена людей, а столбец «кандидат» содержит названия фильмов. –

1

Я считаю, что у меня есть решение проблемы, но проблема с кодировкой все еще может стоять. Фактическая задача - просто получить название фильма, за которым следует символ тире.

Я начинаю с вставки вашего кода, за исключением указания, что аргумент html_nodes является xpath, а не css (забросил ошибки для меня, как и в вашем вопросе).

wiki <- "https://en.wikipedia.org/wiki/89th_Academy_Awards" 
text <- wiki %>% 
     read_html() %>% 
     html_nodes(xpath='//*[@id="mw-content-text"]/table[3]') %>% 
     html_table() 

Затем я останавливаюсь, когда вы определяете Best.Picture. Принуждение к кадру data.frame не нужно, если только я чего-то не упускаю, поскольку это всего лишь вектор.

Best.Picture <- unlist(nw_lst[[1]])[-1] 

Затем я разделил каждую запись в векторе Best.Picture характера, и применять в течение расколото списка (каждый элемент представляет собой вектор выделения каждого символа в каждом элементе вектора). Мы делаем это, чтобы определить, где находится символ магического штриха (который я только что скопировал и вставил непосредственно с терминала, поскольку тире не является «-», но есть какой-то похожий символ (это может означать проблему кодирования, указанную в комментарии.

dash <- sapply(strsplit(Best.Picture, ''), function(x){which(x == '–')}) 

После того как мы определить, где приборную панель находятся в каждом элементе Best.Picture элемента, мы можем использовать substr усечь вектор только ту часть, которая нас интересует. Если вы хотите быть на безопасной стороне, вы могли бы вырезать все до тире - 1 (что также вырезало бы тире), а затем используйте trimws для удаления ведущих или конечных пробелов.

movTitle <- substr(Best.Picture, 1, dash-2) 
Смежные вопросы