如何爬取联合国动态网站多URL数据?含R代码优化需求
联合国SDG伙伴关系网站爬取解决方案
问题背景
计划爬取联合国SDG伙伴关系网站数据用于网络分析:将实体/伙伴设为节点,SDG(可持续发展目标)设为链接,最终生成所需的.csv文件。当前遇到两个核心问题:
- 仅能获取单页18个项目的URL,尝试循环获取423页链接时最多仅能拿到10条;
- 尚未实现进入每个项目页面提取实体及关联SDG信息的逻辑。
解决方案
一、批量获取所有项目URL
网站分页采用page=N的参数形式(N从0到422,共423页),通过遍历所有页码收集URL,同时加入反爬策略避免被限制。
完整代码如下:
library(xml2) library(rvest) library(tidyverse) library(httr) # 设置请求头,模拟浏览器 set_config(user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36")) # 初始化存储数据的空数据框 all_projects <- data.frame( project_name = character(), project_url = character(), stringsAsFactors = FALSE ) # 遍历所有页码(0到422) for(page_num in 0:422) { # 构造当前页URL page_url <- paste0("https://sdgs.un.org/partnerships/browse?page=", page_num) tryCatch({ # 读取页面内容 page_html <- read_html(page_url) # 提取项目名称和URL project_names <- page_html %>% html_elements("span a") %>% html_text2() project_urls <- page_html %>% html_elements("span a") %>% html_attr("href") %>% # 拼接完整URL paste0("https://sdgs.un.org", .) # 将当前页数据并入总数据框 current_page_data <- data.frame( project_name = project_names, project_url = project_urls, stringsAsFactors = FALSE ) all_projects <- bind_rows(all_projects, current_page_data) # 打印进度 cat("已完成第", page_num + 1, "页爬取,累计项目数:", nrow(all_projects), "\n") # 设置延迟,避免请求过于频繁 Sys.sleep(1) }, error = function(e) { # 捕获异常,打印错误信息 cat("爬取第", page_num + 1, "页失败:", e$message, "\n") }) } # 保存所有项目URL到CSV write_csv(all_projects, "sdg_partnerships_urls.csv")
二、提取单个项目页面的实体及SDG信息
基于已获取的项目URL,遍历每个页面提取伙伴实体和关联的SDG目标。需根据页面实际结构调整选择器,以下为通用示例:
# 读取之前保存的项目URL列表 all_projects <- read_csv("sdg_partnerships_urls.csv") # 初始化存储详情的空数据框 project_details <- data.frame( project_name = character(), partner_entity = character(), sdg_target = character(), stringsAsFactors = FALSE ) # 遍历每个项目URL for(i in 1:nrow(all_projects)) { project_url <- all_projects$project_url[i] project_name <- all_projects$project_name[i] tryCatch({ page_html <- read_html(project_url) # 提取伙伴实体(根据页面结构调整选择器) partners <- page_html %>% html_elements(".partner-info .entity-name") %>% html_text2() %>% # 多个伙伴用逗号分隔 paste(collapse = ", ") # 提取关联SDG目标(根据页面结构调整选择器) sdgs <- page_html %>% html_elements(".sdg-tag") %>% html_text2() %>% paste(collapse = ", ") # 存入数据框 current_detail <- data.frame( project_name = project_name, partner_entity = partners, sdg_target = sdgs, stringsAsFactors = FALSE ) project_details <- bind_rows(project_details, current_detail) cat("已完成第", i, "个项目提取,累计:", nrow(project_details), "\n") Sys.sleep(0.5) }, error = function(e) { cat("提取第", i, "个项目失败:", e$message, "\n") }) } # 保存详情数据到CSV write_csv(project_details, "sdg_partnerships_details.csv")
关键注意事项
- 反爬策略:必须加入
Sys.sleep()控制请求频率,避免IP被封禁;保持合法的User-Agent模拟正常浏览器请求。 - 选择器调整:若页面结构更新,需通过浏览器开发者工具(F12)重新定位元素,修改
html_elements()中的选择器。 - 异常处理:使用
tryCatch()捕获请求或解析错误,避免程序中途终止。
内容的提问来源于stack exchange,提问作者jhmayorga
相关产品推荐
相关产品推荐

