Come sbarazzarsi dell'errore durante lo scraping del web in R?

Aug 22 2020

Sto raschiando questo sito Web e ricevo un messaggio di errore se le colonne delle tabelle devono avere dimensioni compatibili.
Cosa devo fare in questo caso?

library(rvest)
library(tidyverse)

url <- "https://www.zomato.com/tr/toronto/drinks-and-nightlife?page=5"
map_dfr(
  .x = url,
  .f = function(x) {
    tibble(
      url = x,
      place = read_html(x) %>%
        html_nodes("a.result-title.hover_feedback.zred.bold.ln24.fontsize0") %>%
        html_attr("title"),
      price = read_html(x) %>%
        html_nodes("div.res-cost.clearfix span.col-s-11.col-m-12.pl0") %>%
        html_text()
    )
  }
) -> df_zomato

Grazie in anticipo.

Risposte

2 Dave2e Aug 22 2020 at 20:26

Il problema è dovuto al fatto che ogni ristorante non ha una registrazione completa. In questo esempio, il 13 ° elemento nell'elenco non includeva il prezzo, quindi il vettore del prezzo aveva 14 elementi mentre il vettore del luogo aveva 15 elementi.

Un modo per risolvere questo problema è trovare il nodo genitore comune e quindi analizzare quei nodi con la html_node()funzione. html_node()restituirà sempre un valore anche se è NA.

library(rvest)
library(dplyr)
library(tibble)


url <- "https://www.zomato.com/tr/toronto/drinks-and-nightlife?page=5"
readpage <- function(url){
   #read the page once
   page <-read_html(url)

   #parse out the parent nodes
   results <- page %>% html_nodes("article.search-result")

   #retrieve the place and price from each parent
   place <- results %>% html_node("a.result-title.hover_feedback.zred.bold.ln24.fontsize0") %>%
      html_attr("title")
   price <- results %>% html_node("div.res-cost.clearfix span.col-s-11.col-m-12.pl0") %>%
      html_text()

   #return a tibble/data,frame
   tibble(url, place, price)
}

readpage(url)

Nota anche nel tuo esempio di codice sopra, hai letto la stessa pagina più volte. Questo è lento e carica il server in più. Questo potrebbe essere visto come un attacco "Denial of Service".
È meglio leggere la pagina una volta in memoria e poi lavorare con quella copia.

Aggiorna
Per rispondere alla tua domanda riguardante più pagine. Avvolgi la funzione sopra in una lapplyfunzione e quindi collega l'elenco dei frame di dati restituiti (o tibble)

dfs <- lapply(listofurls, function(url){ readpage(url)})
finalanswer <- bind_rows(dfs)