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

R批量爬取FIFA球员数据遇404错误 求解决方案

解决fifaindex.com批量爬取404错误的实操方案

先搞懂404错误的常见原因

你遇到的404本质是请求的链接无效或网站拒绝了你的请求,常见情况有三种:

  1. 链接构造错误:fifaindex的年度页面不用直接填年份,而是用对应FIFA版本的编码(比如2023对应230,2012对应120),参数填错直接返回404
  2. 被反爬机制拦截:无间隔频繁请求会被识别为爬虫,网站直接拒绝访问
  3. 页面结构更新:你之前用的链接规则或元素选择器已经失效

一步步解决问题

1. 确认正确的年度参数映射

fifaindex球员列表页的规则是:https://www.fifaindex.com/players/[版本编码]/?page=[页码]
版本编码和年份的对应关系是:

  • 2012 → 120
  • 2013 → 130
  • ...
  • 2023 → 230
    简单说就是年份减去2000再乘10,比如2012-2000=12,12×10=120,构造链接必须用这个编码,不能直接填年份。

2. 给请求加"伪装",避免被反爬

直接用rvest::read_html()会被网站识别为爬虫,必须模拟浏览器请求:

  • 加User-Agent请求头,告诉网站你是正常浏览器访问
  • 每次请求后加延迟,别让网站觉得你在"轰炸"它

3. 加错误处理,跳过无效链接

用tryCatch捕获请求失败的情况,避免整个批量爬取直接崩溃。

调整后的完整代码

library(rvest)
library(httr)
library(dplyr)

# 1. 设置请求头,模拟Chrome浏览器(可换成你自己浏览器的User-Agent)
headers <- add_headers(
  "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
)

# 2. 定义年份和版本编码的映射
year_to_code <- setNames(120:230, 2012:2023)

# 3. 爬取单页球员详情链接的函数
get_page_links <- function(target_year, page_num) {
  # 构造正确的分页链接
  base_url <- paste0("https://www.fifaindex.com/players/", year_to_code[as.character(target_year)], "/?page=", page_num)
  
  tryCatch({
    # 发送带请求头的请求
    res <- GET(base_url, headers)
    # 检查请求是否成功
    if (res$status_code != 200) {
      warning(paste("页面请求失败:", base_url, "状态码:", res$status_code))
      return(NULL)
    }
    # 解析HTML
    page_html <- content(res, "html")
    # 提取球员详情链接(用浏览器F12确认选择器,这里是示例)
    raw_links <- page_html %>% html_elements("a[href^='/player/']") %>% html_attr("href")
    # 补全完整链接
    full_links <- paste0("https://www.fifaindex.com", raw_links)
    return(full_links)
  }, error = function(e) {
    warning(paste("处理页面出错:", base_url, "错误:", e$message))
    return(NULL)
  })
}

# 4. 爬取单个球员详情数据的函数
get_player_info <- function(player_url, target_year) {
  tryCatch({
    res <- GET(player_url, headers)
    if (res$status_code != 200) {
      warning(paste("球员详情请求失败:", player_url))
      return(NULL)
    }
    player_html <- content(res, "html")
    
    # 提取关键信息(根据页面实际结构调整选择器)
    player_name <- player_html %>% html_element("h1") %>% html_text(trim = TRUE)
    overall_rating <- player_html %>% html_element(".rating") %>% html_text(trim = TRUE)
    position <- player_html %>% html_element(".position") %>% html_text(trim = TRUE)
    age <- player_html %>% html_element(".age") %>% html_text(trim = TRUE)
    
    # 整理成数据框
    data.frame(
      姓名 = player_name,
      总评 = overall_rating,
      位置 = position,
      年龄 = age,
      详情链接 = player_url,
      年份 = target_year,
      stringsAsFactors = FALSE
    )
  }, error = function(e) {
    warning(paste("处理球员出错:", player_url, "错误:", e$message))
    return(NULL)
  })
}

# 5. 批量爬取单年度数据的函数
scrape_single_year <- function(target_year) {
  cat("开始爬取", target_year, "年数据...\n")
  all_links <- c()
  current_page <- 1
  
  while(TRUE) {
    cat("正在爬取第", current_page, "页...\n")
    page_links <- get_page_links(target_year, current_page)
    
    # 如果页面无数据或者请求失败,停止分页爬取
    if (is.null(page_links) || length(page_links) == 0) {
      cat("第", current_page, "页无数据,结束该年度分页爬取\n")
      break
    }
    
    all_links <- c(all_links, page_links)
    current_page <- current_page + 1
    Sys.sleep(2) # 每页爬取后延迟2秒
  }
  
  # 去重链接(避免重复爬取同一球员)
  all_links <- unique(all_links)
  cat("共找到", length(all_links), "名球员,开始爬取详情...\n")
  
  # 批量爬取球员详情
  player_data_list <- lapply(all_links, function(link) {
    data <- get_player_info(link, target_year)
    Sys.sleep(1) # 每个球员详情爬取后延迟1秒
    return(data)
  })
  
  # 合并数据框并去掉空值
  final_data <- bind_rows(player_data_list) %>% filter(!is.na(姓名))
  
  # 保存为CSV文件
  output_path <- paste0("FIFA_球员数据_", target_year, ".csv")
  write.csv(final_data, output_path, row.names = FALSE, fileEncoding = "UTF-8")
  cat(target_year, "年数据爬取完成,已保存到:", output_path, "\n")
  
  return(final_data)
}

# 6. 爬取2012-2023年所有数据
for (year in 2012:2023) {
  scrape_single_year(year)
}

额外注意事项

  • 检查robots.txt:先访问https://www.fifaindex.com/robots.txt,确认网站是否允许爬取球员数据,避免违规
  • 更新选择器:如果网站页面结构变化,用浏览器F12重新定位元素的CSS选择器,替换代码里的选择器(比如a[href^='/player/'])
  • 降低请求频率:如果还是被封,把Sys.sleep()的时间调长一点(比如3-5秒)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 10:45:37