基于R语言的IHSN目录爬取:项目描述页动态URL问题求助
解决IHSN目录爬虫中详情页动态URL问题的方案
嘿,我完全懂你的困扰——你已经搞定了列表页的批量爬取,但卡在了获取每个项目的study-description内容上,毕竟每个项目的ID既不连续也没规律。其实问题的核心很简单:你之前的代码只提取了标题文本,没抓取每个标题对应的详情页链接,而这些链接里就藏着我们需要的唯一项目标识!
下面是一步步的解决方案:
1. 修正列表页爬取代码,同时获取标题和详情页链接
首先我们要修改原有代码,不仅提取标题文本,还要把每个标题<a>标签里的href属性(也就是层级1.1的URL,比如/index.php/catalog/7118)抓下来。有了这个链接,就能轻松构造出study-description的目标URL。
library(rvest) library(purrr) # 定义爬取单页列表的函数 scrape_list_page <- function(page_num) { Sys.sleep(5) # 礼貌延时,避免触发服务器反爬机制 base_url <- "http://catalog.ihsn.org/index.php/catalog#_r=&collection=&country=&dtype=&from=1890&page=%d&ps=100&sid=&sk=&sort_by=nation&sort_order=&to=2017&topic=&view=s&vk=" url <- sprintf(base_url, page_num) page <- read_html(url) # 提取项目标题文本 titles <- page %>% html_nodes(".title a") %>% html_text() # 提取详情页基础链接(拼接完整域名) study_base_links <- page %>% html_nodes(".title a") %>% html_attr("href") %>% paste0("http://catalog.ihsn.org", .) # 返回包含标题和链接的dataframe data.frame( title = titles, study_base_link = study_base_links, stringsAsFactors = FALSE ) } # 批量爬取所有417页的列表数据 full_project_list <- map_dfr(1:417, scrape_list_page)
2. 构造study-description URL并爬取描述内容
现在我们有了每个项目的基础链接(比如http://catalog.ihsn.org/index.php/catalog/7118),只需要在末尾拼接/study-description就能得到目标页面的URL。接下来写一个函数来爬取描述内容:
# 定义爬取study-description的函数(添加错误处理避免任务中断) get_study_desc <- possibly(function(base_link) { Sys.sleep(3) # 再次设置延时,保持爬取的友好性 desc_url <- paste0(base_link, "/study-description") desc_page <- read_html(desc_url) # 注意:这里的选择器需要根据页面实际结构调整! # 你可以用浏览器开发者工具(F12)定位描述内容的容器,替换成实际的CSS选择器 description <- desc_page %>% html_nodes(".study-description-content") %>% html_text() %>% paste(collapse = "\n") # 合并多行文本为单条内容 return(description) }, otherwise = NA_character_) # 若爬取失败,返回NA,不中断整体任务 # 批量获取所有项目的描述内容 full_project_list$study_description <- map_chr(full_project_list$study_base_link, get_study_desc)
关键注意事项
- 节点选择器调整:代码里的
.study-description-content是示例选择器,你需要打开一个study-description页面,用浏览器开发者工具定位到描述内容的实际容器,替换成对应的CSS选择器(比如可能是.content-body或其他类名)。 - 错误处理:用
possibly函数包裹爬取逻辑,即使某个页面加载失败,整个批量任务也不会中断,只会返回NA,之后你可以单独处理这些失败的条目。 - 延时设置:务必保留
Sys.sleep的设置,避免给服务器造成过大压力,防止IP被封禁。
这样处理后,你就能得到包含项目标题、基础链接和study-description内容的完整dataframe了!
内容的提问来源于stack exchange,提问作者Mario1950




