使用R语言rvest包批量爬取IMDB电影演职员表并生成结构化表求助
代码调整方案
你的代码核心问题有两点:
get_cast函数将电影名和演员姓名做了拼接,没有单独保留字段- 用
cbind横向拼接演员列表,得到的是宽表,不符合你需要的「一行为一个演员+对应电影信息」的长表结构
第一步:修改get_cast函数
调整后仅返回清洗完成的单个电影的演员列表:
get_cast = function(movie_link2) { movie_page = read_html(movie_link2) # 清洗演员姓名,去掉空格换行 movie_cast = movie_page %>% html_nodes(".primary_photo+ td a") %>% html_text() %>% str_remove_all("[\t\n]") %>% .[. != ""] return(movie_cast) }
注:去掉了原来的
.loadlate选择器,避免爬到不需要的图片相关文本
第二步:调整循环内的演职人员表拼接逻辑
不要用cbind拼接,改为逐部电影生成三列结构的子表,再纵向合并到总表:
library(rvest) library(dplyr) library(stringr) # 初始化表 movies = data.frame() movie_cast = data.frame(stringsAsFactors = FALSE) for (page_result in seq(from = 1, to = 10)) { link = paste0("https://www.imdb.com/list/ls006266261/?st_dt=&mode=detail&page=", page_result, "&ref_=ttls_vm_dtl&sort=list_order,asc") page = read_html(link) # 爬取当前页电影基础信息 name <- page %>% html_nodes(".lister-item-header a") %>% html_text() name <- name[name != " Screen Two"] movie_link = html_node(html_nodes(page, '.lister-item-content'),".lister-item-header a") %>% html_attr("href") %>% paste0("https://www.imdb.com", .) movie_link2 <- file.path(dirname(movie_link), "fullcredits", str_replace(basename(movie_link), "ttls_li_tt", "tt_ql_cl")) # 清洗年份,去掉括号方便后续关联 year <- html_node(html_nodes(page, '.lister-item-content'),".text-muted.unbold") %>% html_text() %>% str_extract("\\d{4}") year <- year[!year %in% c("IMDb user rating (average)","Number of votes","Release year or range")] rating <- html_node(html_nodes(page, '.lister-item-content'),".certificate") %>% html_text() director <- html_node(html_nodes(page, '.lister-item-content'),".text-small a:nth-child(1)") %>% html_text() director <- director[director != "gibboanx"] gross <- html_node(html_nodes(page, '.lister-item-content'),".ghost~ .text-muted+ span") %>% html_text() gross <- gross[gross != "|"] meta <- html_node(html_nodes(page, '.lister-item-content'), '.ratings-metascore span') %>% html_text() genre <- html_node(html_nodes(page, '.lister-item-content'),".genre") %>% html_text() # 拼接主电影表 movies <- bind_rows(movies, data.frame(name, year, rating, director, gross, meta, genre, stringsAsFactors = FALSE)) # 逐部处理演员列表 for (i in seq_along(movie_link2)) { # 防止请求过快被封IP,可自行调整等待时长 Sys.sleep(1) cast_list = get_cast(movie_link2[i]) # 生成当前电影的演职人员子表 if(length(cast_list) > 0) { cast_df = data.frame( 电影名称 = name[i], 上映年份 = year[i], 演员姓名 = cast_list, stringsAsFactors = FALSE ) # 合并到总演职人员表 movie_cast = bind_rows(movie_cast, cast_df) } } print(paste("Page:", page_result)) }
第三步:导出结果
运行完成后直接导出为CSV即可用Excel打开,直接和你的主数据集做关联匹配:
# 导出主电影表 write.csv(movies, "主电影表.csv", row.names = FALSE, fileEncoding = "utf-8-sig") # 导出演职人员表 write.csv(movie_cast, "演职人员表.csv", row.names = FALSE, fileEncoding = "utf-8-sig")
内容的提问来源于stack exchange,提问作者JustBeginning
相关产品推荐
相关产品推荐

