2015-05-08 13 views
8

Verwendung rvest in R eine web-Seite abzuschaben, würde Ich mag das Äquivalent von innerHTML von einem Knoten vor der Anwendung html_text, insbesondere zu ändern Zeilenumbrüche in Zeilenumbrüche zu extrahieren.R: rvest innerHTML- Extrahieren

Beispiel der gewünschten Funktionalität:

library(rvest) 
doc <- read_html('<html><p class="pp">First Line<br />Second Line</p>') 
innerHTML(doc, ".pp") 

erzeugen, werden in folgende Ausgabe:

[1] "<p class=\"pp\">First Line<br>Second Line</p>" 

Mit rvest 0.2 dies durch toString.XMLNode

erreicht werden kann
# run under rvest 0.2 
library(XML) 
html('<html><p class="pp">First Line<br />Second Line</p>') %>% 
    html_node(".pp") %>% 
    toString.XMLNode 
[1] "<p class=\"pp\">First Line<br>Second Line</p>" 

mit den neueren rvest 0.2.0.900 das funktioniert nicht mehr.

# run under rvest 0.2.0.900 
library(XML) 
html_node(doc,".pp") %>% 
    toString.XMLNode 
[1] "{xml_node}\n<p>\n[1] <br/>" 

Die gewünschte Funktionalität ist in der Regel in der write_xml Funktion Paket xml2 auf dem rvest jetzt hängt - wenn auch nur write_xml seinen Ausgang auf eine Variable geben könnte, anstatt in eine Datei schreiben beharren. (auch eine textConnection wird nicht akzeptiert).

Als Abhilfe ich in eine Datei vorübergehend schreiben:

# extract innerHTML, workaround: write/read to/from temp file 
html_innerHTML <- function(x, css, xpath) { 
    file <- tempfile() 
    html_node(x,css) %>% write_xml(file) 
    txt <- readLines(file, warn=FALSE) 
    unlink(file) 
    txt 
} 
html_innerHTML(doc, ".pp") 
[1] "<p class=\"pp\">First Line<br>Second Line</p>" 

damit ich kann dann beispielsweise die Zeilenumbrüche in new-line Zeichen verwandeln:

html_innerHTML(doc, ".pp") %>% 
    gsub("<br\\s*/?\\s*>","\n", .) %>% 
    read_html %>% 
    html_text 
[1] "First Line\nSecond Line" 

Ist es gibt einen besseren Weg, dies mit bestehenden Funktionen von zB zu tun rvest, xml2, XML oder andere Pakete? Insbesondere möchte ich vermeiden, auf die Festplatte zu schreiben.

+1

Scheint, wie ein Problem auf github Einreichung könnte produktiver sein ... – hadley

+0

Für Follow-up wurde dies als ein Problem gegeben und [schließlich gelöst] (https://github.com/hadley/rvest/ Probleme/87). Die Antwort ist einfach, 'as.character' zu verwenden. – r2evans

Antwort

0

Wie @R2evans notiert, as.character(doc) ist die Lösung.

Sie das letzte Mal Code-Schnipsel In Bezug auf die die <br> -separated Text aus dem Knoten während der Konvertierung <br> Newline extrahieren will, ist es eine Abhilfe in der derzeit ungelöst rvest issue #175, comment #2:

Die vereinfachte Version für dieses Problem:

doc <- read_html('<html><p class="pp">First Line<br />Second Line</p>') 

# r2evan's solution: 
as.character(rvest::html_node(doc, xpath="//p")) 
##[1] "<p class=\"pp\">First Line<br>Second Line</p>" 

# [email protected]'s solution, simplified: 
innerHTML <- function(x, trim = FALSE, collapse = "\n"){ 
    paste(xml2::xml_find_all(x, ".//text()"), collapse = collapse) 
} 
innerHTML(doc) 
## [1] "First Line\nSecond Line"