You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用R语言爬取加拿大人口金字塔各年份性别年龄分布数据

如何用R获取加拿大统计局人口金字塔页面1851-2043全年份性别-年龄分布数据?

我正在使用R编程语言,需要从加拿大统计局的加拿大历史人口金字塔页面获取下拉菜单中1851-2043所有年份的性别-年龄分布数据,期望输出格式如下:

year gender  age percent_of_population
1  1975   Male   25                    3%
2  1975 Female   25                    2%
3  1975   Male   26                    1%
4  1975 Female   26                    2%
5  ....   ....  ...                   ...
6  1976   Male   25                    4%
7  1976 Female   25                    3%
8  1976   Male   26                    2%
9  1976 Female   26                    1%
10  ...    ... ....                   ...

目前未找到可直接下载全年份数据的按钮,查看网页源码也未发现可用的直接数据标签,请问如何解决该问题?是否可以使用Selenium实现?


解决方案:使用R结合Selenium实现数据抓取

完全可以用Selenium解决这个问题——因为页面数据是动态加载的,需要模拟用户选择年份的交互操作来获取对应数据。以下是具体实现步骤:

1. 安装并加载所需包

先确保安装并加载RSelenium(用于模拟浏览器操作)和tidyverse(用于数据整理):

install.packages(c("RSelenium", "tidyverse"))
library(RSelenium)
library(tidyverse)

2. 初始化Selenium浏览器驱动

启动Chrome浏览器(如需用Firefox,可调整对应驱动参数):

# 启动浏览器驱动
rD <- rsDriver(browser = "chrome", port = 4567L)
remDr <- rD[["client"]]

# 访问目标页面
url <- "https://www12.statcan.gc.ca/census-recensement/2021/dp-pd/dv-vd/pyramid/index-en.htm"
remDr$navigate(url)

3. 循环遍历年份并抓取数据

定位年份下拉菜单,提取所有目标年份,逐个选择后抓取对应性别-年龄数据:

# 定位年份下拉菜单元素
year_select <- remDr$findElement(using = "id", value = "yearSelect")
# 获取所有年份选项文本
year_options <- year_select$findChildElements(using = "tag name", value = "option") %>%
  sapply(function(x) x$getElementText()) %>%
  unlist()

# 筛选1851-2043的目标年份
target_years <- year_options[year_options >= "1851" & year_options <= "2043"]

# 初始化空数据框存储结果
final_data <- data.frame()

# 循环处理每个年份
for (year in target_years) {
  # 选择当前年份
  year_select$sendKeysToElement(list(year))
  # 等待页面加载数据(可根据网络速度调整等待时间)
  Sys.sleep(2)
  
  # 提取男性年龄组和占比数据
  male_ages <- remDr$findElements(using = "css selector", value = ".male .age-group") %>%
    sapply(function(x) x$getElementText()) %>%
    unlist()
  male_percents <- remDr$findElements(using = "css selector", value = ".male .percent") %>%
    sapply(function(x) x$getElementText()) %>%
    unlist()
  
  # 提取女性年龄组和占比数据
  female_ages <- remDr$findElements(using = "css selector", value = ".female .age-group") %>%
    sapply(function(x) x$getElementText()) %>%
    unlist()
  female_percents <- remDr$findElements(using = "css selector", value = ".female .percent") %>%
    sapply(function(x) x$getElementText()) %>%
    unlist()
  
  # 整理男性数据为数据框
  male_df <- data.frame(
    year = year,
    gender = "Male",
    age = male_ages,
    percent_of_population = male_percents,
    stringsAsFactors = FALSE
  )
  
  # 整理女性数据为数据框
  female_df <- data.frame(
    year = year,
    gender = "Female",
    age = female_ages,
    percent_of_population = female_percents,
    stringsAsFactors = FALSE
  )
  
  # 合并当前年份数据到总结果
  final_data <- rbind(final_data, male_df, female_df)
  
  # 打印进度
  cat("已完成年份:", year, "\n")
}

4. 数据格式调整(可选)

如果需要将年龄范围(如"0-4")转为单年龄数值,可添加以下处理:

# 示例:提取年龄范围的起始值作为年龄列数值
final_data <- final_data %>%
  mutate(age = str_extract(age, "^\\d+") %>% as.integer())

5. 保存数据并关闭浏览器

# 保存为CSV文件
write.csv(final_data, "canada_population_pyramid_data.csv", row.names = FALSE)

# 关闭浏览器和驱动
remDr$close()
rD$server$stop()

注意事项

  • 页面元素的CSS选择器可能随网站更新变化,若运行出错,需用浏览器开发者工具重新定位元素。
  • 可根据网络速度调整Sys.sleep()的等待时间,确保数据完全加载后再提取。
  • 频繁请求可能触发反爬机制,建议适当增加等待间隔,避免被限制访问。

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:53:10