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

readxl读取1997-2003版Excel列不全,爬取欧盟原油周报遇解析问题

解决欧盟石油公报原始Excel文件读取列不全的问题

看起来你遇到的是旧式Excel(.xls,97-2003格式)的兼容性问题,readxl对这类复杂格式的文件支持有限,加上可能的文件下载不规范,导致只读取到第一列数据。下面是一步步的解决方案:

第一步:修正爬取与下载逻辑

首先,你的爬取代码可以更精准,并且一定要用二进制模式下载文件(xls是二进制格式,直接远程读取或文本模式下载会损坏文件):

library(rvest)
library(readxl)
library(tidyverse)
library(httr)

# 目标页面
base_url <- "http://ec.europa.eu/energy/observatory/reports/"
page <- read_html(base_url)

# 精准筛选含"raw_data"的xls文件链接
raw_xls_links <- page %>% 
  html_nodes("a[href$='.xls']") %>%  # 先过滤所有xls文件
  html_attr("href") %>% 
  str_subset("raw_data") %>%  # 只保留含raw_data的链接
  paste0(base_url, .)  # 拼接成完整绝对路径

# 创建临时文件夹存放下载的文件
dir.create("raw_oil_data", showWarnings = FALSE)

# 批量下载文件(二进制模式)
walk(raw_xls_links, function(link) {
  file_name <- basename(link)
  download.file(link, destfile = file.path("raw_oil_data", file_name), mode = "wb")
})

第二步:选择兼容旧式xls的读取工具

readxl对旧式BIFF格式的xls支持不够完善,推荐用以下两个包来处理:

方案1:使用gdata(依赖Perl)

gdata的read.xls是处理旧式xls的老牌工具,兼容性很强:

# 安装依赖(Windows用户需要先安装Perl环境,推荐Strawberry Perl)
install.packages("gdata")
library(gdata)

# 读取单个文件测试
test_file <- list.files("raw_oil_data", pattern = ".xls", full.names = TRUE)[1]
oil_data <- read.xls(test_file, sheet = 1, header = TRUE, stringsAsFactors = FALSE)

方案2:使用XLConnect(依赖Java)

如果不想装Perl,可以试试XLConnect,它通过Java处理Excel文件,对复杂格式支持也不错:

install.packages("XLConnect")
library(XLConnect)

# 加载工作簿并读取数据
wb <- loadWorkbook(test_file)
oil_data <- readWorksheet(wb, sheet = 1, startRow = 1, startCol = 1)

第三步:处理特殊格式问题

如果还是存在列不全的情况,大概率是文件里有合并单元格或非标准表头位置:

  1. 先查看文件的所有工作表:
# 用readxl查看工作表名
excel_sheets(test_file)
  1. 如果数据不在第一个工作表,指定对应的sheet名称读取:
oil_data <- read.xls(test_file, sheet = "DataSheet", skip = 2)  # skip跳过前两行非数据行
  1. 处理合并单元格:旧式xls里的合并单元格会导致readxl只读取第一个单元格的值,用XLConnect可以展开合并区域:
wb <- loadWorkbook(test_file)
merge_regions <- getMergeRegions(wb, sheet = 1)

# 遍历合并区域,填充所有单元格的值
for (region in merge_regions) {
  # 获取合并单元格的初始值
  fill_value <- readWorksheet(wb, sheet = 1, 
                              startRow = region$startRow, startCol = region$startCol,
                              endRow = region$startRow, endCol = region$startCol)
  # 填充整个合并区域
  writeWorksheet(wb, fill_value, sheet = 1,
                 startRow = region$startRow, startCol = region$startCol,
                 endRow = region$endRow, endCol = region$endCol)
}

# 保存修改后的工作簿(可选)
saveWorkbook(wb, "fixed_oil_data.xls")

# 读取处理后的数据
oil_data <- readWorksheet(wb, sheet = 1)

总结

核心问题是旧式xls格式的兼容性,只要确保文件完整下载,再用更兼容的工具读取,配合调整工作表、起始行等参数,就能解决列不全的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:23:56