2015-05-08 2 views
8

Использования rvest в R, чтобы очистить веб-страницу, я хотел бы извлечь эквивалент innerHTML из узла, в частности, изменить разрывы строк в строки до применения html_text.R: rvest извлечения innerHTML

Пример желаемой функциональности:

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

должен создавать следующий вывод:

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

rvest 0.2 С это может быть достигнуто за счет toString.XMLNode

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

с новыми rvest 0.2.0.900 Это больше не работает.

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

Желаемая функциональность обычно доступны в функции write_xml пакета xml2 на котором rvest теперь зависит - если только write_xml может дать свой вывод в переменную вместо настаивания, чтобы записать в файл. (также textConnection не принимается).

Как обходной я могу временно записать в файл:

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

с этим я могу затем, например, преобразовать теги линии разрыва в новые строки символов:

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

Is существует лучший способ сделать это с помощью существующих функций, например rvest, xml2, XML или другие пакеты? В частности, я бы хотел избежать записи на жесткий диск.

+1

Похоже подачи вопрос о GitHub может быть более продуктивным ... – hadley

+0

Для наблюдения, это был добавлен как вопрос и [в конце концов решена] (https://github.com/hadley/rvest/ вопросы/87). Ответ - просто использовать 'as.character'. – r2evans

ответ

0

Как отметил @ r2evans, решение as.character(doc).

Что касается вас последний фрагмент кода, который хочет извлечь <br> -разделенное текст из узла при преобразовании <br> в конец строки, есть обходной путь в настоящее время нерешенной rvest issue #175, comment #2:

Упрощенная версия этой проблемы:

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"