Удаление html-тегов из строки в R

Я пытаюсь прочитать источник веб-страницы в R и обрабатывать его как строки. Я пытаюсь извлечь абзацы и удалить теги html из текста абзаца. Я столкнулся с следующей проблемой:

Я попробовал реализовать функцию для удаления тегов html:

cleanFun=function(fullStr)
{
 #find location of tags and citations
 tagLoc=cbind(str_locate_all(fullStr,"<")[[1]][,2],str_locate_all(fullStr,">")[[1]][,1]);

 #create storage for tag strings
 tagStrings=list()

 #extract and store tag strings
 for(i in 1:dim(tagLoc)[1])
 {
   tagStrings[i]=substr(fullStr,tagLoc[i,1],tagLoc[i,2]);
 }

 #remove tag strings from paragraph
 newStr=fullStr
 for(i in 1:length(tagStrings))
 {
   newStr=str_replace_all(newStr,tagStrings[[i]][1],"")
 }
 return(newStr)
};

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

test="junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk"

Целью было бы получить:

cleanFun(test)="junk junk junk junk"

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

Ответы

Ответ 1

Это может быть достигнуто просто с помощью регулярных выражений и семейства grep:

cleanFun <- function(htmlString) {
  return(gsub("<.*?>", "", htmlString))
}

Это также будет работать с несколькими тегами html в одной строке!

Ответ 2

Вы также можете сделать это с помощью двух функций в пакете rvest:

library(rvest)

strip_html <- function(s) {
    html_text(read_html(s))
}

Пример вывода:

> strip_html("junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk")
[1] "junk junk junk junk"

Обратите внимание, что вы не должны использовать регулярные выражения для анализа HTML.

Ответ 3

Другой подход, используя tm.plugin.webmining, который использует XML внутренне.

> library(tm.plugin.webmining)
> extractHTMLStrip("junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk")
[1] "junk junk junk junk"

Ответ 4

Подход с использованием пакета qdap:

library(qdap)
bracketX(test, "angle")

## > bracketX(test, "angle")
## [1] "junk junk junk junk"

Ответ 5

Лучше не анализировать html с помощью регулярных выражений. Открывать теги RegEx, за исключением автономных тегов XHTML

Используйте пакет, например XML. Измените код html в синтаксическом анализе, используя, например, htmlParse, и используйте xpaths, чтобы найти нужные вам значения.

UPDATE:

Чтобы ответить на вопрос OP

require(XML)
xData <- htmlParse('yourfile.html')
xpathSApply(xData, 'appropriate xpath', xmlValue)

Ответ 6

Во-первых, ваша строка темы вводит в заблуждение; в строке, которую вы разместили, нет обратных косых черт. Вы стали жертвой одного из классических промахов: не так плохо, как участвовать в наземной войне в Азии, но все равно. Вы ошибаетесь в использовании R \ для обозначения экранированных символов для литеральных обратных косых черт. В этом случае \" означает знак двойной кавычки, а не два буквальных символа \ и ". Вы можете использовать cat, чтобы увидеть, что на самом деле будет выглядеть строка, если бы экранированные символы были обработаны буквально.

Во-вторых, вы используете регулярные выражения для анализа HTML. (Они не отображаются в вашем коде, но они используются под капотом в str_locate_all и str_replace_all.) Это еще один из классических ошибок; см. здесь для более подробной информации.

В-третьих, вы должны упомянуть в своем посте, что используете пакет stringr, но это лишь незначительная ошибка при сравнении.

Ответ 7

Это может быть проще с sub или gsub?

> test  <- "junk junk<a href=\"/wiki/abstraction_(mathematics)\" title=\"abstraction (mathematics)\"> junk junk"
> gsub(pattern = "<.*>", replacement = "", x = test)
[1] "junk junk junk junk"

Ответ 8

Я перепробовал весь твой код, но он у меня не сработал. Я пытаюсь очистить 79 000 текстовых файлов, которые хранятся локально на моем компьютере. Я использую функцию gsub, которая очищает теги html, но оставляет имя тега, например, после очистки div. Так что это очень плохо. Далее, если я уберу. /?- и другие подобные символы, они также будут очищены в моем тексте, что тоже плохо. Так есть ли у кого-нибудь идеи, как решить эту проблему? Я просто хотел бы убрать все HTML-теги, чтобы иметь чистый текст для применения анализа настроений.

Код:

for (i in 1:nrow(d1800)) {

  dest.filename <- paste0("1800/1800_8-K_", d1800$date.filed[i], "_", d1800$accession.number[i], ".txt")

  # Read filing 
  filing.text <- readLines(dest.filename)

  # Extract data from first <DOCUMENT> to </DOCUMENT>
  filing.text <- filing.text[(grep("<DOCUMENT>", filing.text, ignore.case = TRUE)[1]):(grep("</DOCUMENT>", filing.text, ignore.case = TRUE)[1])]  

  # Preprocessing the filing text: REGULAR EXPRESSION
  filing.text <- gsub("\\n|\\t|,", " ", filing.text)
  filing.text <- paste(filing.text, collapse=" ")
  filing.text <- gsub(" ", "", filing.text)
  filing.text <- gsub("[[:punct:]]", "", filing.text, perl=T)
  filing.text <- gsub("[[:digit:]]", "", filing.text, perl=T)
  filing.text <- iconv(filing.text, from = 'UTF-8', to = 'ASCII//TRANSLIT')
  filing.text <- tolower(filing.text)
  filing.text <- gsub("\\s{2,}", " ", filing.text)
}