Dúvida Scrapping Site IMDB

Oi pessoal, boa tarde!
Estou tentando fazer um web-scrapping do IMDB, criei uma função pra me retornar um tibble com os dados que estou tentando pegar… Mas ao executar o código, recebo a seguinte mensagem de erro:

 Erro: `x` must be a string of length 1 

Abaixo segue o código desenvolvido até aqui:

library(rvest)
library(tidyverse)
link<-"https://www.imdb.com/title/tt0386676/episodes?season="
temporadas<-c(1:9)
links<-c(paste0(link,temporadas))

extrair_informacoes<-function(url){
  x<- url %>% 
    read_html()
  #temporada
  temp<- x %>% 
    html_nodes("#episode_top") %>% 
    html_text()
  #numero episodio
  n_ep<- x %>% 
    html_nodes(".info meta")  %>%  
    html_attr("content")
  #avaliação
  nota<- x %>% 
    html_nodes("#episodes_content > div.clear > div.list.detail.eplist > div:nth-child(1) > div.info > div.ipl-rating-widget > div.ipl-rating-star.small > span.ipl-rating-star__rating") %>% 
    html_text()
  #nome do episodio
  nome_ep<- x %>% 
    html_nodes(".info strong") %>% 
    html_text()
  
  tibble(temporada = temp,num_ep=n_ep,notas=nota,nome=nome_ep)
}

dados<- links %>% extrair_informacoes()

O que esse erro representa e como posso resolvê-lo?

Oi Ozias, tudo bem?

Que legal essa ideia! Executei seu código e ele funcionou bem… até a última linha. Esse erro aconteceu pois a sua função foi criada de uma forma onde ela recebe um argumento de tamanho = 1 (length = 1), e você oferece como argumento um vetor de tamanho = 9.

Dá pra resolver com a função purrr::map_dfr(), onde aplicamos a função .f em todos os elementos do vetor .x, e retornamos como um data frame (sendo que os resultados serão empilhados como novas linhas/rows). Por isso é _dfr = “data frame rows”.

Veja o exemplo abaixo:

library(rvest)
library(tidyverse)
link <- "https://www.imdb.com/title/tt0386676/episodes?season="
temporadas <- c(1:9)
links <- c(paste0(link, temporadas))

extrair_informacoes <- function(url) {
  x <- url %>%
    read_html()
  # temporada
  temp <- x %>%
    html_nodes("#episode_top") %>%
    html_text()
  # numero episodio
  n_ep <- x %>%
    html_nodes(".info meta") %>%
    html_attr("content")
  # avaliação
  nota <- x %>%
    html_nodes("#episodes_content > div.clear > div.list.detail.eplist > div:nth-child(1) > div.info > div.ipl-rating-widget > div.ipl-rating-star.small > span.ipl-rating-star__rating") %>%
    html_text()
  # nome do episodio
  nome_ep <- x %>%
    html_nodes(".info strong") %>%
    html_text()

  tibble(temporada = temp, num_ep = n_ep, notas = nota, nome = nome_ep)
}

# Erro: Error: `x` must be a string of length 1
# dados <- links %>% extrair_informacoes()


# Como resolver?
dados <- purrr::map_dfr(.x = links, .f = extrair_informacoes)

dplyr::glimpse(dados)
#> Rows: 188
#> Columns: 4
#> $ temporada <chr> "Season 1", "Season 1", "Season 1", "Season 1", "Season 1", …
#> $ num_ep    <chr> "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", …
#> $ notas     <chr> "7.5", "7.5", "7.5", "7.5", "7.5", "7.5", "8.7", "8.7", "8.7"…
#> $ nome      <chr> "Pilot", "Diversity Day", "Health Care", "The Alliance", "Ba…

Created on 2021-06-05 by the reprex package (v2.0.0.9000)

Abraços!

2 Curtidas

Oi @beatrizmilz , bom dia! Tudo bem? Muito obrigado pela ajuda!! Sua solução funcionou perfeitamente…

Agora me veio outra dúvida, mais relacionado a parte de web-scraping mesmo… Notei que na parte das notas, ele veio repetindo a nota do primeiro episódio de cada temporada pra o restante dos episódios… Tentei inclusive alterar o selector ali dentro do html_nodes() , mas sem sucesso por enquanto…

Você teria alguma sugestão de como poderia ser corrigido isso? Pegando corretamente a nota de cada episódio…

Oi @beatrizmilz , uma atualização… Consegui alterar o código de maneira a pegar corretamente a nota de cada episódio… Na função extrair_informacoes(), na parte da nota, alterei o selector pra esse:

  #avaliação
  nota<- x %>% 
    html_nodes(".ipl-rating-star.small .ipl-rating-star__rating") %>% 
    html_text() %>% 
    as.numeric()

Mais uma vez, muito obrigado pela ajuda!! :smiley:

Oi Ozias! Só vi agora, mas que bom que resolveu!

Abraços