R语言多页面网页爬取问题:循环重复获取第0页内容
问题分析与解决方案
核心问题:URL拼接错误
你代码里的sprintf没有正确替换页码——原base_url缺少格式化占位符,导致每次循环请求的都是同一个URL(https://npin.cdc.gov/search?=type%3Aorganization&page=),服务器默认返回第0页内容,这是重复获取同一页的根本原因。
除此之外,代码还存在for循环赋值无效、数据列不匹配、直接修改全局数据框易混乱等问题,下面是修正后的完整代码及说明:
修正后的代码
library(tidyverse) library(rvest) # 带格式化占位符的基础URL,%d用于替换页码 base_url <- "https://npin.cdc.gov/search?=type%3Aorganization&page=%d" # 定义单页爬取函数,避免全局变量修改 scrape_page <- function(page_num) { page_url <- sprintf(base_url, page_num) new_page <- read_html(page_url) # 提取组织基础信息 org_name <- new_page %>% html_nodes(".block-field-blocknodeorganizationtitle") %>% html_text2() street <- new_page %>% html_nodes(".address-line1") %>% html_text2() city <- new_page %>% html_nodes(".locality") %>% html_text2() state <- new_page %>% html_nodes(".administrative-area") %>% html_text2() zip <- new_page %>% html_nodes(".postal-code") %>% html_text2() # 提取服务区块 services <- new_page %>% html_nodes(".services-fieldset") # 遍历每个组织的服务信息,构建数据框 map_dfr(seq_along(services), function(i) { temp <- services[i] %>% html_nodes(".field__items") # 从第2个元素开始(第1个为服务标题,无有效内容) map_dfr(seq(2, length(temp)), function(j) { service_label <- temp[j] %>% html_nodes(".field-label") %>% html_text() %>% str_remove(":") service_items <- temp[j] %>% html_nodes(".field__item") %>% html_text() %>% str_c(collapse = ",") tibble( org_name = org_name[i], street = street[i], city = city[i], state = state[i], zip = zip[i], service_category = service_label, service_items = service_items ) }) }) } # 爬取0-3页并合并结果 result <- map_dfr(0:3, scrape_page) # 查看最终结果 result
关键修正点说明
- URL占位符修复:给
base_url添加%d占位符,sprintf会自动将页码替换到对应位置,确保每次请求不同页面。 - 替换无效for循环:用
map_dfr(tidyverse工具)替代原for循环,避免new_result赋值为NULL的问题,同时自动合并数据框,代码更简洁可控。 - 列匹配修复:原代码初始数据框定义了6列,但只插入3列,修正后确保每个条目包含所有需要的字段(组织名称、地址、服务分类/项目),避免数据错位。
- 避免全局变量修改:将单页爬取逻辑封装为函数,每个页面生成独立数据框后再合并,降低调试难度。
内容的提问来源于stack exchange,提问作者Mando
相关产品推荐
相关产品推荐

