使用rvest爬取Booking.com遇报错,需实现缺失值返回NA
解决Booking.com爬取数据时缺失字段返回NA及报错问题
问题根源
- 报错原因:原代码中
titles_page是经html_text()转换后的字符向量,后续对其调用html_element()必然报错——因为html_element()仅支持XML/HTML节点对象,不支持字符类型。 - 缺失字段无NA:直接从页面全局提取所有标题、价格、评分,当某酒店无评分/价格时,对应向量长度不匹配,且不会自动补NA,导致最终数据框行数不一致。
解决方案
核心思路是先定位每个酒店的卡片容器节点,再从每个容器内单独提取字段,确保每个酒店对应一条记录,缺失字段自动返回NA:
- 先抓取页面中所有酒店的卡片父节点(Booking的酒店卡片通常用
div[data-testid='property-card']标识) - 对每个卡片节点分别提取标题、价格、评分,缺失时
html_element()会返回NA - 改用数据框逐步合并的方式替代向量拼接,避免长度不匹配问题
- 增加延迟避免触发反爬机制
修改后的完整代码
# 加载必要包 library(rvest) library(dplyr) library(httr) # 基础URL与搜索参数 base_url <- "https://www.booking.com/searchresults.it.html" params <- list( ss = "Firenze%2C+Toscana%2C+Italia", efdco = 1, label = "booking-name-L*Xf2U1sq4*GEkIwcLOALQS267777916051%3Apl%3Ata%3Ap1%3Ap22%2C563%2C000%3Aac%3Aap%3Aneg%3Afi%3Atikwd-65526620%3Alp9069992%3Ali%3Adec%3Adm%3Appccp", aid = 376363, lang = "it", sb = 1, src_elem = "sb", src = "index", dest_id = -117543, dest_type = "city", ac_position = 0, ac_click_type = "b", ac_langcode = "it", ac_suggestion_list_length = 5, search_selected = "true", search_pageview_id = "2e375b14ad810329", ac_meta = "GhAyZTM3NWIxNGFkODEwMzI5IAAoATICaXQ6BGZpcmVAAEoAUAA%3D", checkin = "2023-06-11", checkout = "2023-06-18", group_adults = 2, no_rooms = 1, group_children = 0, sb_travel_purpose = "leisure" ) # 初始化空数据框存储结果 hotel_data <- data.frame() # 循环爬取页面 for (page_num in 1:35) { # 构造当前页URL url <- modify_url(base_url, query = c(params, page = page_num)) # 读取页面HTML page <- read_html(url) # 抓取当前页所有酒店卡片节点 hotel_cards <- page %>% html_elements("div[data-testid='property-card']") # 从每个卡片提取字段,缺失自动返回NA titles_page <- hotel_cards %>% html_element("div[data-testid='title']") %>% html_text2() prices_page <- hotel_cards %>% html_element("span[data-testid='price-and-discounted-price']") %>% html_text2() ratings_page <- hotel_cards %>% html_element("div[aria-label^='Punteggio di']") %>% html_text2() # 组合当前页数据并合并到总数据框 page_df <- data.frame( title = titles_page, price = prices_page, rating = ratings_page ) hotel_data <- bind_rows(hotel_data, page_df) # 增加延迟避免反爬 Sys.sleep(2) } # 查看结果 print(hotel_data)
关键说明
html_text2():相比html_text(),它能更好处理多余的空格、换行,返回更干净的文本- 卡片节点提取:确保每个酒店对应一个节点,所有字段提取都基于该节点,保证行数完全匹配
- 延迟设置:
Sys.sleep(2)让爬虫每爬一页暂停2秒,降低被网站封禁的风险
内容的提问来源于stack exchange,提问作者Anisa B.
相关产品推荐
相关产品推荐

