RVest: Исправление ошибки «Замена имеет нулевую длину» в цикле - PullRequest
0 голосов
/ 04 ноября 2019

Я хотел бы вычеркнуть определенную часть HTML-кода из веб-сайта. Требуемый объект находится не на каждой странице цикла ниже, поэтому некоторые значения равны NA. Но всякий раз, когда какой-либо объект отсутствует, весь цикл останавливается.

Я пробовал этот код для очистки без циклов, что оказалось отлично работает. Здесь я исключил все значения, которые либо недостижимы, либо не представляют интереса.

BJ <- data.frame( Wohnungs_ID = ID, Baujahr = ifelse (nchar(Baujahr)==0 | nchar(Baujahr)>6, NA, Baujahr), stringsAsFactors = F

В соответствующем случае я хочу очистить две конкретные переменные, которые не всегда перечислены. Url - это список ссылок, которые я удалил.

library(rvest)  
library(magrittr)
library(tidyr)  
library(ggplot2) 
library(stringr) 
library(jsonlite) 
library(purrr)  
library(dplyr)  

immo_webp <- read_html ("https://www.immobilienscout24.de/Suche/S-2/Wohnung-Miete/Rheinland-Pfalz/Koblenz")


# URLs 

base = 'https://www.immobilienscout24.de/expose/'

urls <- sapply(read_html("https://www.immobilienscout24.de/Suche/S-2/Wohnung-Miete/Rheinland-Pfalz/Koblenz")%>%
                 html_nodes('article')%>%
                 html_attr('data-obid'), function (url){paste0(base, url)})
print(urls)

# ID bilden

substring(urls, 1, 1)
ID <- substring(urls, 41)

Baujahr <- c(1 : 20)
Energie <- c(1 : 20)

for (i in urls){

  aktuellewohnung <- read_html(url(i))

  Baujahr[i] <- aktuellewohnung %>%
    html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(1) > dd") %>%
    html_text()
  Energie[i] <- aktuellewohnung %>%
    html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(7) > dd") %>%
    html_text()  
} 

Я получил следующую ошибку.

Error in Baujahr[i] <- aktuellewohnung %>% html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(1) > dd") %>%  : 

replacement has length zero

Я хочу, чтобы этот цикл работал, сохраняя отсутствующие значения как NA. Надеюсь, вы можете мне помочь. Заранее большое спасибо.

Ответы [ 2 ]

1 голос
/ 04 ноября 2019

Используйте это вместо цикла:

results_df <- lapply(urls, function(u) {
  message(u)

  aktuellewohnung <- read_html(u)

  Baujahr <- aktuellewohnung %>%
    html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(1) > dd") %>%
    html_text()
  Energie <- aktuellewohnung %>%
    html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(7) > dd") %>%
    html_text() 
  tibble(
    Baujahr = ifelse(length(Baujahr) == 0, NA, Baujahr),
    Energie = ifelse(length(Energie) == 0, NA, Energie)
  )
}) %>% 
  bind_rows()

Цикл lapply вернет список data.frames, который имеет NA, если поле не может быть найдено. bind_rows() превращает их в один data.frame.

0 голосов
/ 04 ноября 2019

Попробуйте использовать trycatch функцию при назначении значения:

Baujahr[i] <- tryCatch({aktuellewohnung %>%
    html_nodes("#is24-content > div.grid-item.padding-desk-right-xl.desk-two-thirds.lap-one-whole.desk-column-left.flex-item.palm--flex__order--1.lap--flex__order--1 > div.is24-ex-details.main-criteria-headline-size.two-column-layout > div.criteriagroup.flex.flex--wrap.criteria-group--spacing.padding-top-s > div.criteriagroup.criteria-group--border.criteria-group--two-columns.criteria-group--spacing > dl:nth-child(1) > dd") %>%
    html_text()},error = function(cond){NA})
...