R에서 'rvest'를 사용하여 웹 스크래핑을 할 때 특정 행 정보를 기반으로 추가 변수를 데이터에 병합하는 가장 좋은 방법은 무엇입니까?

라미 롬프

나는 현재 영화 데이터를 추출하기 위해 IMDB 웹 사이트를 웹 스크랩하고 있습니다.

이 문제를 어떻게 해결할 수 있는지 알고 싶습니다.

library(tidyverse)
library(data.table)
library(rvest)
library(janitor)

#top rated movies website 
url <- 'https://www.imdb.com/chart/top/?ref_=nv_mv_250'

# extract the title of the movies using rvest

titles <- url %>%
  read_html() %>%
  html_nodes(' .titleColumn a') %>%
  html_text() %>%
  as.data.table() %>%
  setnames(. ,old = colnames(.), new='title') 

# extract links to each of the titles, this will be the reference 

links <- url %>%
  read_html() %>%
  html_nodes('.titleColumn a') %>%
  html_attr('href') %>%
  as.data.table() %>%
  setnames(. ,old = colnames(.), new='links') 

# creating a DT with the data

movies <- cbind(titles,links)

제목과 링크가있는 영화 DT가 열로 표시됩니다.

이제 링크를 사용하여 각 영화의 추가 데이터를 추출해 보겠습니다.

계속해서 첫 번째 행을 예로 사용하겠습니다.


#the first link in movies  

link <- 'https://www.imdb.com/title/tt0111161/?pf_rd_m=A2FGELUUNOQJNL&pf_rd_p=e31d89dd-322d-4646-8962-327b42fe94b1&pf_rd_r=NJ52X0MM1V9FKSPBT46G&pf_rd_s=center-1&pf_rd_t=15506&pf_rd_i=top&ref_=chttp_tt_1'

# selector for budget data (this will not change)

select <- '.txt-block:nth-child(15) , .txt-block:nth-child(14) , #titleDetails .txt-block:nth-child(13) , #titleDetails .txt-block:nth-child(12)'


# get budget data

budget <- link %>%
  read_html() %>%
  html_nodes(select) %>%
  html_text() %>%
  gsub('\\n','',.) %>%
  str_split(.,'\\:')%>%
  as.data.table() %>%
  janitor::row_to_names(row_number = 1) %>%
  setnames(.,old=colnames(.),new= tolower(gsub(' ','_' , str_trim(colnames(.)))))

budget[,(colnames(budget))] <- lapply(budget,function(x) str_extract_all(x, "(\\$) *([0-9,]+)"))

이제 예산 정보가 포함 된 1x4 테이블이 있습니다.

영화의 각 링크에 대한 데이터를 가져 와서 DT에 병합하여 6 개의 열이있는 최종 DT를 만들고 싶습니다. '제목', '링크'+ 4 개의 예산 변수. 각 행의 링크를 매개 변수로 사용하고 'lapply'를 사용하여 예산 데이터를 가져 오는 코드를 포함하는 함수를 만들려고했지만 이것이 올바른 접근 방식이라고 생각하지 않습니다.

효율적인 방법으로 이에 대한 해결책이 있는지 확인하고 싶습니다.

도와 주셔서 감사합니다.

diego_v

나는 이것이 당신의 문제를 해결할 것이라고 생각합니다.

# selector for budget data (this will not change)
select <- '.txt-block:nth-child(15) , .txt-block:nth-child(14) , #titleDetails .txt-block:nth-child(13) , #titleDetails .txt-block:nth-child(12)'

# get budget data
## As function
get_budget = function(link,select){
budget <- link %>%
  read_html() %>%
  html_nodes(select) %>%
  html_text() %>%
  gsub('\\n','',.) %>%
  str_split(.,'\\:')%>%
  as.data.table() %>%
  janitor::row_to_names(row_number = 1) %>%
  setnames(.,old=colnames(.),new= tolower(gsub(' ','_' , str_trim(colnames(.)))))

budget[,(colnames(budget))] <- lapply(budget,function(x) str_extract_all(x, "(\\$) *([0-9,]+)"))
return(budget)
}

#As your code is slow I'll subset movies to have 10 rows:
movies = movies[1:10,]
tmp = 
lapply(movies[, links], function(x) 
  get_budget(link = paste0("https://www.imdb.com/",x),select=select )) %>% 
  rbindlist(., fill = T)

movies = cbind(movies, tmp)

결과는 다음과 같습니다. movies_result

마지막으로,이 작은 조언이 코드를 더 멋지게 만들 것이라고 생각합니다.

  • setnames.에서 필요하지 않습니다 magrittr. 당신의 코드를 자동으로 이해합니다.
  • 가능하면 setnames(. ,old = colnames(.), new='links'). 귀하의 경우에는 setnames('links')모든 변수의 이름을 변경 하기 때문에 필요 합니다.
  • setnames(dt,old = oldnames, new=newnames) oldnames가 names (dt)와 같지 않을 때만 필요합니다.
  • DT또 다른 R인기있는 라이브러리 이기 때문에 완전히 관련이없는 data.table것이 data.table을 data.table.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관