如何用purrr::possibly()配合map_dfr()处理网页爬取的HTTP 403错误
解决rvest批量爬取时的错误中断问题(用purrr::possibly实现容错)
直接上可运行的实现代码,核心是把单页爬取逻辑封装成独立函数,再用purrr::possibly()包装,指定出错时返回的默认数据结构,同时记录坏链接:
# 加载所需包 library(rvest) library(purrr) library(dplyr) # 1. 定义单页爬取函数 scrape_single_page <- function(url) { # 可选:设置User-Agent避免403(很多网站会拦截默认R请求) session <- html_session(url, user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") # 提取目标数据(这里以标题和正文为例,根据你的需求修改) title <- session %>% html_element("h1") %>% html_text2() content <- session %>% html_element(".content") %>% html_text2() # 返回数据框 tibble( url = url, title = title, content = content, is_error = FALSE # 标记是否为正常爬取 ) } # 2. 用possibly包装爬取函数,指定出错时的默认返回值 safe_scrape <- possibly(scrape_single_page, otherwise = function(url) { tibble( url = url, title = NA_character_, content = NA_character_, is_error = TRUE # 标记为错误链接 ) }) # 3. 准备待爬取的链接列表(包含正常和错误链接测试) urls <- c( "https://example.com", # 正常链接 "https://example.com/bad-link-404", # 404错误 "https://some-site-that-blocks-r.com" # 可能返回403 ) # 4. 批量爬取并合并结果 scraped_data <- map_dfr(urls, safe_scrape) # 查看结果,错误链接会被标记 print(scraped_data)
关键细节说明:
- 包装逻辑:
possibly()的第一个参数是你的爬取函数,otherwise参数必须是一个能接收相同参数(这里是url)的函数,返回和正常爬取结果结构完全一致的数据框,这样map_dfr才能顺利合并所有结果。 - 错误标记:通过
is_error字段可以快速筛选出坏链接,后续可以单独处理这些链接(比如重试、记录日志)。 - 403问题优化:很多网站返回403是因为识别出了R的默认请求头,所以在
html_session里设置user_agent模拟浏览器请求,能大幅减少这类错误。 - 扩展处理:如果需要更细粒度的错误捕获(比如区分403和404),可以在
scrape_single_page里用tryCatch()捕获具体错误类型,再返回不同标记的结果。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

