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

请求实现R语言下《Die Gartenlaube》全年份期刊内容的批量抓取方案

请求实现R语言下《Die Gartenlaube》全年份期刊内容的批量抓取方案

嘿Marco!你已经把单一年份的抓取逻辑跑通了,这一步超棒!现在要把这个能力扩展到所有年份对吧?我帮你把代码重构了一下,封装成可复用的函数,再加上批量处理的逻辑,这样就能轻松拿到所有年份的year-issue-title-text数据啦。

第一步:准备年份与期数的映射数据

首先把你提供的年份-期数表格先定义好,我们后面要用到它来对应每个年份的总期数:

# 定义年份与对应期数的数据框
year_issues <- structure(
  list(
    Year = c(1853, 1854, 1855, 1856, 1857, 1858, 1859,
             1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870,
             1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881,
             1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892,
             1893, 1894, 1895, 1896, 1897, 1898, 1899),
    count = c(52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 49L, 52L,
              52L, 51L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L, 52L,
              52L, 52L, 52L, 52L, 53L, 52L, 52L, 52L, 52L, 52L, 53L, 52L,
              52L, 28L, 52L, 28L, 52L, 52L, 52L, 52L, 53L, 28L, 28L)
  ),
  class = c("tbl_df", "tbl", "data.frame"),
  row.names = c(NA, -47L)
)

第二步:封装单年份抓取函数

我把你原来的单年份抓取逻辑封装成了一个函数,这样不管哪个年份,只要传入年份和期数就能直接调用,还加了边界处理避免报错:

library(rvest)
library(dplyr)
library(tibble)

# 定义抓取单一年份期刊的函数
scrape_gartenlaube_year <- function(target_year, num_issues) {
  # 初始化存储列表
  year_data <- list()
  
  for(i in 1:num_issues){
    # 构造当期URL
    url <- paste0("https://de.wikisource.org/wiki/Die_Gartenlaube_(", target_year, ")/Heft_", i)
    
    # 读取HTML文档
    html_document  <- read_html(url)
    
    # 提取标题(去掉第一个无关标题)
    title <- html_document %>% 
      html_nodes("h2") %>% 
      html_text() %>% 
      .[-1]
    
    # 提取对应标题的正文内容
    text <- character()
    # 处理标题数量不足的边界情况,避免循环报错
    if(length(title) >= 2){
      for(j in 1:(length(title)-2)){
        # 用XPath定位两个标题之间的段落
        txt <- html_document %>% 
          html_nodes(xpath = paste0("//p[preceding-sibling::h2[. = '",
                                   title[j],
                                   "'] and following-sibling::h2[. = '",
                                   title[j+1], "']]")) %>% 
          html_text()
        
        # 合并段落文本
        text[j] <- paste(txt, collapse = '')
      }
    }
    
    # 对齐标题和文本长度(处理长度不一致的情况)
    n <- max(length(title), length(text))
    length(title) <- n
    length(text) <- n
    
    # 组合当期数据,添加期数列
    issue_df <- tibble(title = title, text = text, issue = i)
    year_data[[i]] <- issue_df
  }
  
  # 合并全年数据,添加年份列
  year_full_df <- bind_rows(year_data) %>% 
    mutate(year = target_year)
  
  return(year_full_df)
}

第三步:批量抓取所有年份

这里给你两种方案,选你习惯的就行:

方案1:传统for循环(直观易调试)

all_gartenlaube_data <- tibble()

for(row in 1:nrow(year_issues)){
  current_year <- year_issues$Year[row]
  current_num_issues <- year_issues$count[row]
  
  # 打印抓取进度,方便追踪
  cat("正在抓取", current_year, "年的内容,共", current_num_issues, "期...\n")
  
  year_df <- scrape_gartenlaube_year(current_year, current_num_issues)
  all_gartenlaube_data <- bind_rows(all_gartenlaube_data, year_df)
}

方案2:函数式写法(更简洁)

用purrr包的map2_dfr函数,直接把年份和期数配对传入函数,自动合并结果:

library(purrr)

all_gartenlaube_data <- map2_dfr(
  .x = year_issues$Year,
  .y = year_issues$count,
  .f = ~{
    cat("正在抓取", .x, "年的内容,共", .y, "期...\n")
    scrape_gartenlaube_year(.x, .y)
  }
)

最后验证结果

跑完之后,all_gartenlaube_data就是你想要的完整数据框啦,包含year、issue、title、text四个字段,和你1853年的结果格式完全一致,只是覆盖了所有年份。

备注:内容来源于stack exchange,提问作者Marco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 15:33:15