2017-02-17 7 views
-1

Ich habe es geschafft, diese Wikipedia Seite Oscars Nominations zu kratzen und die Tabelle unter "Nominees" zu extrahieren. Ich kann anhand der folgenden Tabelle durch die der Code erhalten:Web Scraping Wikipedia - String Manipulation

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

Welche gibt eine ‚Liste‘, wie der Name ‚text‘

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

Ich versuche, die Ergebnisse in einem df zu setzen und entfernen Sie dann ein unbrauchbare Zeile und dann 'strsplit' auf der Zeile break Regex '\ n' in der 'nw_lst', die eine andere Liste aber viel sauberer mit 23 Elementen ausgibt, die jeder Oscar-Nominierung mit den unten aufgeführten Titeln entspricht. Ich möchte dann die Liste in 2 df, eine für die beste Bildnominierung und die zweite df mit den anderen Nominierungen analysieren.

Also hier ist mein Problem, sobald ich die Nominierungen getrennt habe, möchte ich den Text aufräumen. Das Problem ist, dass aus irgendeinem Grund nichts in dem "striperr" -Paket den gesamten unnötigen Text außer dem Filmtitel entfernen kann.

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") 

Aber wenn ich die Struktur von df in meiner Umgebung zu untersuchen und klicken Sie auf den blauen Pfeil Vektor-Klassen, um zu sehen und Sie die Maus über die chr Vektor schweben, aber es hat seltsame Formen innerhalb des Zeichenvektor und hat diese |__truncated__ innerhalb in Die Zeichenfolge ist jedoch nicht sichtbar, wenn die Zeichenfolge in der Konsole überprüft wird.

Ich möchte nur den besten Weg wissen, um über diese Zeichenfolgen zu reinigen, oder eine andere Möglichkeit, nur die Titelnamen für jede Nominierung innerhalb der HTML-Knoten unter <ul> und <li> parse zu bekommen? Ich weiß nicht viel über grundlegende HTML-Code-Bedeutungen, außer durch den Quellcode zu schauen und zu finden, was ich mit dem Selector-Gadget brauche.

+0

„es seltsame Formen innerhalb des Zeichenvektor“ - das ist Problem wahrscheinlich eine Codierung (siehe 'Encoding '). Haben Sie die HTML-Parsing-Funktionen im Paket 'XML' ausprobiert? – Jean

Antwort

2

Ein weiterer Ansatz ist jeder einzelne <td> dann die Metadaten zur Verfügung verwenden Ziel:

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

Genau das habe ich versucht zu erreichen. Wie hast du diesen XPath am Anfang deines Codes bekommen? Hast du ein Tool benutzt oder einfach nur den HTML Code angesehen? – mikeymike

+0

Nur durch Blick auf den Code. XPath & ich haben eine langjährige Hassliebe. – hrbrmstr

+0

Das funktioniert gut für das beste Bild, aber wenn wir zum Beispiel "Bester Regisseur" betrachten, steht der Name des Regisseurs an erster Stelle. So enthält die Spalte "Film" schließlich Namen von Personen und die Spalte "Kandidat" Filmtitel. –

1

Ich glaube, ich habe eine Lösung für das Problem, aber die Codierung Problem kann noch bestehen. Die eigentliche Aufgabe besteht darin, einfach auf den Filmtitel zu kommen, auf den der Bindestrich folgt.

Ich beginne mit einer Paste von Ihrem Code, mit der Ausnahme, dass die html_nodes Argument ist Xpath und nicht CSS (warf Fehler für mich, wie es in Ihrer Frage ist).

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

Dann stoppe ich, wenn Sie Best.Picture definieren. Es in ein data.frame zu zwingen ist unnötig, es sei denn, ich vermisse etwas, da es nur ein Vektor ist.

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

Dann aufgeteilt I jeden Eintrag in dem Zeichen Best.Picture Vektor und gelte im aufgespalten Liste (jedes Element ein Vektor jedes Zeichen in jedem Vektorelement zu isolieren). Wir tun dies, um zu bestimmen, wo das magische Bindestrichsymbol ist (das ich gerade kopiert und direkt vom Terminal eingefügt habe, da das Bindestrich nicht "-" ist, sondern ein ähnliches Symbol (dies könnte das im Kommentar erwähnte Codierproblem bedeuten.

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

Nachdem wir bestimmen, wo der Strich in jedem Element des Best.Picture Element befindet, können wir substr verwenden den Vektor nur den Teil zu kürzen, dass wir wichtig sind. Wenn Sie auf der sicheren Seite sein wollten, könnten Sie Schneiden Sie alles bis zum Bindestrich - 1 (was auch den Bindestrich abschneiden würde) und verwenden Sie dann trimws, um führende oder nachstehende Leerzeichen zu entfernen.

movTitle <- substr(Best.Picture, 1, dash-2)