2016-09-22 9 views
0

Я пытаюсь очистить вики для определенных определений, связанных с астрономией, для моего проекта. Код работает очень хорошо, но я не могу избежать 404s. Я попробовал tryCatch. Я думаю, что здесь что-то не хватает.Скрестить с петлей и избежать ошибки 404

Я ищу способ преодолеть 404s во время работы цикла. Вот мой код:

library(rvest) 
library(httr) 
library(XML) 
library(tm) 


topic<-c("Neutron star", "Black hole", "sagittarius A") 

for(i in topic){ 

    site<- paste("https://en.wikipedia.org/wiki/", i) 
    site <- read_html(site) 

    stats<- xmlValue(getNodeSet(htmlParse(site),"//p")[[1]]) #only the first paragraph 
    #error = function(e){NA} 

    stats[["topic"]] <- i 

    stats<- gsub('\\[.*?\\]', '', stats) 
    #stats<-stats[!duplicated(stats),] 
    #out.file <- data.frame(rbind(stats,F[i])) 

    output<-rbind(stats,i) 

} 
+0

Предполагаю, вы имеете в виду примечание об ошибке, а затем переходите к следующей итерации цикла? –

+0

Соответствующий/возможно дублирующийся пост http://stackoverflow.com/questions/8093914 – zx8754

+0

Как примечание, посмотрите http://stackoverflow.com/questions/14693956/how-can-i-prevent-rbind-from -geting-really-slow-as-dataframe-grows-large – konvas

ответ

0
  1. Построить переменную URLs в цикле, используя sprintf.
  2. Извлечь весь текст тела из узлов абзаца.
  3. Удалите все векторы, возвращающие длину (0)
  4. Я добавил шаг, чтобы включить весь текст тела аннотированного по предварённому [paragraph - n] для reference..because хорошо ... друзья не давайте данные друзья отходов или сделать несколько запросов HTTP.
  5. Построение кадра данных для каждой итерации в вашем списке тем в форме ниже:
  6. Bind все из data.frames в списке в один ...

  7. wiki_url: должно быть очевидно

  8. тема: из списка темы
  9. info_summary: первый абзац (вы упомянули в своем посте)
  10. all_info: в случае, если вам нужно знать more..ya.

  11. Обратите внимание, что я использую старую, исходный вариант rvest

  12. для простоты понимания я просто присваивая имя HTML для того, что бы ваш read_html.

    library(rvest) 
        library(jsonlite) 
    
        html <- rvest::read_html 
    
        wiki_base <- "https://en.wikipedia.org/wiki/%s" 
    
        my_table <- lapply(sprintf(wiki_base, topic), function(i){ 
    
         raw_1 <- html_text(html_nodes(html(i),"p")) 
    
         raw_valid <- raw_1[nchar(raw_1)>0] 
    
         all_info <- lapply(1:length(raw_valid), function(i){ 
          sprintf(' [paragraph - %d] %s ', i, raw_valid[[i]]) 
         }) %>% paste0(collapse = "") 
    
         data.frame(wiki_url = i, 
            topic = basename(i), 
            info_summary = raw_valid[[1]], 
            trimws(all_info), 
            stringsAsFactors = FALSE) 
    
        }) %>% rbind.pages 
    
        > str(my_table) 
        'data.frame': 3 obs. of 4 variables: 
        $ wiki_url : chr "https://en.wikipedia.org/wiki/Neutron star"  "https://en.wikipedia.org/wiki/Black hole" "https://en.wikipedia.org/wiki/sagittarius A" 
        $ topic  : chr "Neutron star" "Black hole" "sagittarius A" 
        $ info_summary: chr "A neutron star is the collapsed core of a large star (10–29 solar masses). Neutron stars are the smallest and densest stars kno"| __truncated__ "A black hole is a region of spacetime exhibiting such strong gravitational effects that nothing—not even particles and electrom"| __truncated__ "Sagittarius A or Sgr A is a complex radio source at the center of the Milky Way. It is located in the constellation Sagittarius"| __truncated__ 
        $ all_info : chr " [paragraph - 1] A neutron star is the collapsed core of a large star (10–29 solar masses). Neutron stars are the smallest and "| __truncated__ " [paragraph - 1] A black hole is a region of spacetime exhibiting such strong gravitational effects that nothing—not even parti"| __truncated__ " [paragraph - 1] Sagittarius A or Sgr A is a complex radio source at the center of the Milky Way. It is located in the constell"| __truncated__ 
    

EDIT

Функция для обработки ошибок .... возвращает логическое. Итак, это станет нашим первым шагом.

url_works <- function(url){ 
tryCatch(
    identical(status_code(HEAD(url)),200L), 
    error = function(e){ 
     FALSE 
    }) 
} 

Основываясь на вашем использовании «экзопланеты» Вот все применимые данные со страницы вики:

exo_data <- (html_nodes(html('https://en.wikipedia.org/wiki/List_of_exoplanets'),'.wikitable')%>%html_table)[[2]] 

str(exo_data)

'data.frame': 2048 obs. of 16 variables: 
$ Name       : chr "Proxima Centauri b" "KOI-1843.03" "KOI-1843.01" "KOI-1843.02" ... 
$ bf       : int 0 0 0 0 0 0 0 0 0 0 ... 
$ Mass (Jupiter mass)   : num 0.004 0.0014 NA NA 0.1419 ... 
$ Radius (Jupiter radii)  : num NA 0.054 0.114 0.071 1.012 ... 
$ Period (days)     : num 11.186 0.177 4.195 6.356 19.224 ... 
$ Semi-major axis (AU)   : num 0.05 0.0048 0.039 0.052 0.143 0.229 0.0271 0.053 1.33 2.1 ... 
$ Ecc.       : num 0.35 1.012 NA NA 0.0626 ... 
$ Inc. (deg)     : num NA 72 89.4 88.2 87.1 ... 
$ Temp. (K)      : num 234 NA NA NA 707 ... 
$ Discovery method    : chr "radial vel." "transit" "transit" "transit" ... 
$ Disc. Year     : int 2016 2012 2012 2012 2010 2010 2010 2014 2009 2005 ... 
$ Distance (pc)     : num 1.29 NA NA NA 650 ... 
$ Host star mass (solar masses) : num 0.123 0.46 0.46 0.46 1.05 1.05 1.05 0.69 1.25 0.22 ... 
$ Host star radius (solar radii): num 0.141 0.45 0.45 0.45 1.23 1.23 1.23 NA NA NA ... 
$ Host star temp. (K)   : num 3024 3584 3584 3584 5722 ... 
$ Remarks      : chr "Closest exoplanet to our Solar System. Within host star’s habitable zone; possibl 
y Earth-like." "controversial" "controversial" "controversial" ... 

функцию тестирования наши url_works на случайной выборке таблица

tests <- dplyr::sample_frac(exo_data, 0.02) %>% .$Name 

Теперь давайте построим таблицу ref с именем, url для проверки и логическим, если URL-адрес действителен, и за один шаг создайте список из двух фреймов данных, один из которых содержит URL-адреса, которые не существуют. и другие, которые это делают. Те, которые проверяют, могут выполнять описанную выше функцию без проблем. Таким образом, обработка ошибок выполняется до того, как мы начнем пытаться разобрать в цикле. Избегает головных болей и дает справочную информацию о том, какие предметы нужно дополнительно изучить.

b <- ldply(sprintf('https://en.wikipedia.org/wiki/%s',tests), function(i){ 
data.frame(name = basename(i), url_checked = i,url_valid = url_works(i)) 
}) %>%split(.$url_valid) 

> str(b) 
List of 2 
$ FALSE:'data.frame': 24 obs. of 3 variables: 
    ..$ name  : chr [1:24] "Kepler-539c" "HD 142 A c" "WASP-44 b" "Kepler-280 b" ... 
    ..$ url_checked: chr [1:24] "https://en.wikipedia.org/wiki/Kepler-539c" "https://en.wikipedia.org/wiki/HD 142 A c" "https://en.wikipedia.org/wiki/WASP-44 b" "https://en.wikipedia.org/wiki/Kepler-280 b" ... 
    ..$ url_valid : logi [1:24] FALSE FALSE FALSE FALSE FALSE FALSE ... 
$ TRUE :'data.frame': 17 obs. of 3 variables: 
    ..$ name  : chr [1:17] "HD 179079 b" "HD 47186 c" "HD 93083 b" "HD 200964 b" ... 
    ..$ url_checked: chr [1:17] "https://en.wikipedia.org/wiki/HD 179079 b" "https://en.wikipedia.org/wiki/HD 47186 c" "https://en.wikipedia.org/wiki/HD 93083 b" "https://en.wikipedia.org/wiki/HD 200964 b" ... 
    ..$ url_valid : logi [1:17] TRUE TRUE TRUE TRUE TRUE TRUE ... 

Очевидно, что второй элемент списка содержит фрейм данных с действительными URLs, поэтому применять предыдущую функцию в столбце URL-адрес в том, что один. Обратите внимание, что я попробовал таблицу всех планет для объяснения ... Есть 2400 некоторых нечетных имен, так что проверка займет минуту или два, чтобы запустить в вашем случае. Надеюсь, что это обернется для вас.

+0

Я пытался очистить текст регулярным выражением, поэтому я попробовал tm-пакет. Мне нужен только первый параграф, чтобы проверить мой код. Я знаю, что это не займет много времени, но у меня есть длинный список тем. То, что вы дали, работает достаточно хорошо, но я не вижу шагов для обработки ошибок. –

+0

Себастьян, вы правы! Я ищу способ пропустить URL-адрес ошибки или отметить ошибку в переменной и перейти к следующему элементу. –

+0

где был бы корень ошибки ... вот что неясно. является ли ошибка в том, что элемент в списке не может иметь страницу? ваш пример не выдавал ошибок ... поэтому я предположил, что это основа. вам нужно выяснить, откуда возникла ошибка ... и насколько регулярное выражение ... это довольно расплывчато, но неважно. –