使用R(rvest)爬取网页时将缺失值替换为NA的问题求助
解决rvest爬取IMDB时缺失值导致数据框生成失败的问题
你遇到的核心问题是直接全局抓取单个字段的节点时,缺失该节点的电影不会被返回对应值,导致各字段向量长度不一致,所以没法生成data.frame。之前的方法都是在处理已抓取到的内容,但根本没补全那些缺失条目的位置。
比如certificate字段,页面里有1部电影没有这个节点,所以html_nodes(".certificate")只返回49个值,而name是50个,自然报错。gross缺失更多,只有37个值,差距更大。
解决方案
正确的做法是先按每个电影的容器节点遍历,每个电影单独提取所有字段,这样即使某个字段缺失,也能在对应位置填充NA。
完整修正代码
library(rvest) library(purrr) link <- "https://www.imdb.com/search/title/?title_type=feature&num_votes=25000,&genres=action&sort=user_rating,desc&start=1&ref_=adv_nxt" page <- read_html(link) # 先抓取所有电影的容器节点(每个.lister-item对应一部电影) movie_containers <- page %>% html_nodes(".lister-item") # 遍历每个容器,提取单个电影的所有字段 movies <- map_dfr(movie_containers, function(container) { tibble( name = container %>% html_node(".lister-item-header a") %>% html_text(), year = container %>% html_node(".text-muted.unbold") %>% html_text(), certificate = container %>% html_node(".certificate") %>% html_text() %>% replace(is.na(.), NA), runtime = container %>% html_node(".runtime") %>% html_text(), genre = container %>% html_node(".genre") %>% html_text(trim = TRUE), imdb_rating = container %>% html_node(".ratings-imdb-rating strong") %>% html_text(), director = container %>% html_node(".text-muted+ p a:nth-child(1)") %>% html_text(), number_of_votes = container %>% html_node(".sort-num_votes-visible span:nth-child(2)") %>% html_text(), gross = container %>% html_node(".ghost~ .text-muted+ span") %>% html_text() %>% replace(is.na(.), NA) ) }) # 查看结果 head(movies)
关键说明
- 用
html_node()(单数)代替html_nodes()(复数):在单个容器里用html_node(),如果找不到对应节点会返回NA,而不是直接忽略该条目。 map_dfr():把每个容器返回的tibble合并成一个大的数据框,自动对齐行。- 对缺失的字段(certificate、gross),用
replace(is.na(.), NA)确保空值被转为NA(其实html_node()找不到节点时已经返回NA,这里是双重保险)。
为什么之前的方法无效?
- 你之前的代码都是全局抓取所有同类型节点,缺失节点的电影不会出现在结果向量里,导致向量长度不足。比如
html_nodes(".certificate")只返回有该节点的49个值,而不是50个(其中1个为NA)。 - 像
replace(!nzchar(.),NA)这种方法,只能处理已抓取到的空字符串,但问题是那些缺失的条目根本没被抓到,所以向量里没有这些位置,自然没法替换。
运行修正后的代码,movies会是50行的数据框,certificate和gross字段中缺失的位置会显示NA,不会再报长度不一致的错误。
内容的提问来源于stack exchange,提问作者Shashivydyula
相关产品推荐
相关产品推荐

