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)
第三步:处理特殊格式问题
如果还是存在列不全的情况,大概率是文件里有合并单元格或非标准表头位置:
- 先查看文件的所有工作表:
# 用readxl查看工作表名 excel_sheets(test_file)
- 如果数据不在第一个工作表,指定对应的sheet名称读取:
oil_data <- read.xls(test_file, sheet = "DataSheet", skip = 2) # skip跳过前两行非数据行
- 处理合并单元格:旧式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
相关产品推荐
相关产品推荐

