XML / HTML 表格 / Web 抓取(静态 HTML)

发布: (2025年12月12日 GMT+8 03:49)
6 min read
原文: Dev.to

Source: Dev.to

快速工作区准备

# 检查工作目录
getwd()

# 设置工作目录(如果必须)
setwd("/path/to/project")

# 使用干净的环境(请谨慎使用)
rm(list = ls())

# 显示当前目录下的文件
list.files()

Base R 与现代 tidyverse / 高性能包

  • Base R (read.table, read.csv, read.delim) – 在任何地方都能使用,灵活。
  • readr (read_csv, read_delim) – 更快,解析一致,友好于 tidyverse。
  • data.table::fread – 对大 CSV 类文件极其快速。
  • readxl – 读取 Excel 的最佳选择(无外部依赖)。
  • haven – 读取 SAS/SPSS/Stata(通过 ReadStat)的最佳选择。
  • jsonlite – 现代 JSON 解析。
  • DBI + 各种数据库后端 – 关系型数据库的标准接口。
  • arrow – Feather/Parquet 以及与 Python/Spark 的互操作;适合大规模列式数据。

CSV / 分隔文本

推荐

  • 小到中等文件:readr::read_csv()
  • 超大文件:data.table::fread()vroom::vroom()

示例

# readr – tidy 默认,打印解析问题
install.packages("readr")
library(readr)

df  <- read_csv("data/sales.csv")               # 逗号分隔
df2 <- read_delim("data/data.txt", "\t")        # 制表符分隔
# data.table – 超快,自动类型检测
install.packages("data.table")
library(data.table)

dt <- fread("data/sales.csv")
# vroom – 惰性加载,适合大量文件
install.packages("vroom")
library(vroom)

df_v <- vroom("data/sales.csv")

常用参数

  • locale = locale(encoding = "UTF-8") – 处理字符编码。
  • col_types = cols(...) – 强制列类型(避免误解析)。
  • na = c("", "NA", "NULL") – 指定缺失值标记。
  • n_max – 只读取前 N 行(快速预览)。

Excel (XLS / XLSX)

推荐

  • readxl::read_excel() – 无 Java 依赖,可靠。
  • tidyxl, openxlsx – 用于公式或写入。

示例

install.packages("readxl")
library(readxl)

# 读取第一张工作表
df <- read_excel("data/book.xlsx")

# 按名称或索引读取特定工作表
df_sheet3 <- read_excel("data/book.xlsx", sheet = "Sales")
df_sheet2 <- read_excel("data/book.xlsx", sheet = 2)

# 读取指定范围
df_range <- read_excel("data/book.xlsx", range = "A1:F100")

JSON

推荐

  • jsonlite::fromJSON() – 稳健;在适当情况下将数组转换为数据框。
install.packages("jsonlite")
library(jsonlite)

# 从本地文件读取
j <- fromJSON("data/doc.json", flatten = TRUE)

# 从 URL 读取
j2 <- fromJSON("https://api.example.com/data")

提示: 如果 JSON 包含嵌套列表,使用 flatten = TRUE 或手动 tidyr::unnest() 进行整洁化。

XML / HTML 表格 / 网页抓取(静态 HTML)

推荐

  • xml2 + rvest 用于 HTML 抓取 / 表格提取。
  • XML 用于更高级的 XML 解析(但一般推荐 xml2)。
install.packages(c("xml2", "rvest"))
library(xml2)
library(rvest)

page   <- read_html("https://example.com/page-with-tables")
tables <- html_table(html_nodes(page, "table"))  # tibble 列表

类 Excel 与遗留格式(ODS、Google Sheets)

Google Sheets

install.packages("googlesheets4")
library(googlesheets4)

sheet <- read_sheet("https://docs.google.com/spreadsheets/...")

ODS

install.packages("readODS")
library(readODS)

ods_data <- read_ods("data/file.ods")

SAS / SPSS / Stata

推荐

  • haven(快速,保留标签变量)。
  • foreign 较旧;推荐使用 haven
install.packages("haven")
library(haven)

df_sas   <- read_sas("data/data.sas7bdat")
df_spss  <- read_sav("data/data.sav")
df_stata <- read_dta("data/data.dta")

提示: haven 会保留值标签(labelled 类)。使用 labelled::to_factor() 转换为因子。

MATLAB / Octave

install.packages("R.matlab")
library(R.matlab)

m <- readMat("data/matrix.mat")

对于 Octave 文本数据:

install.packages("foreign")
library(foreign)

oct_data <- read.octave("data/file.oct")

Parquet、Feather、Arrow — 现代列式格式

install.packages("arrow")
library(arrow)

# 读取 Parquet
tbl <- read_parquet("data/data.parquet")

# 写入 Parquet
write_parquet(df, "out/data.parquet")

优势: Arrow 支持离线内存、零拷贝读取,是大规模流水线的理想选择。

ODBC / 关系型数据库(SQL Server、Postgres、MySQL 等)

推荐做法

  • DBI + 驱动包(RPostgresRMySQLodbc)——标准接口。
  • pool 用于在应用中进行连接池管理。

示例:通过 DBI 连接 PostgreSQL

install.packages(c("DBI", "RPostgres"))
library(DBI)

con <- dbConnect(RPostgres::Postgres(),
                 dbname = "mydb",
                 host   = "db.example.com",
                 port   = 5432,
                 user   = "me",
                 password = "pw")

# 执行查询
df <- dbGetQuery(con, "SELECT * FROM schema.table LIMIT 1000")

# 分块获取大表
res   <- dbSendQuery(con, "SELECT * FROM big_table")
chunk <- dbFetch(res, n = 10000)

# 清理
dbClearResult(res)
dbDisconnect(con)

ODBC(Windows / DSN)

install.packages("odbc")
library(DBI)

con <- dbConnect(odbc::odbc(), DSN = "my_dsn", UID = "user", PWD = "pw")
dbListTables(con)
dbDisconnect(con)

提示: 避免在巨表上使用 SELECT *——只选取需要的列并在 SQL 端进行过滤。

云存储(S3、GCS、Azure)

  • S3: aws.s3;Arrow 可直接从 S3 URI 读取。
  • Google Cloud Storage: gcsfs(较少使用)或 Arrow/GCS 集成。
  • Azure: AzureStor.

使用 aws.s3 的示例

install.packages("aws.s3")
library(aws.s3)

# 配置 AWS 凭证(环境变量或 ~/.aws/credentials)
s3read_using(FUN = read.csv, object = "s3://my-bucket/data.csv")

Arrow 也可以读取 S3 上的 Parquet:

arrow::read_parquet("s3://bucket/path/file.parquet")

分块读取 / 流式处理大文件

  • 使用数据库导入并查询子集。
  • data.table::fread(select = ...) 只读取特定列。
  • vroom + dplyr 用于延迟读取。
  • 复杂分块:readr::read_lines_chunked()LaFiotools 包。

使用 LaF 的示例

install.packages("LaF")
library(LaF)

laf   <- laf_open_csv("big.csv",
                      column_types = c("integer", "double", "string"),
                      nrows = 1e8)
block <- laf[1:100000, ]  # 前 10 万行

解析日期、时间和类型

正确的解析可以避免后续的意外。

install.packages("lubridate")
library(lubridate)

df$date     <- ymd(df$date_string)          # "2023-07-01"
df$datetime <- ymd_hms(df$ts)                # "2023-07-01 08:45:00"

readr 中使用 col_types,或在 fread 中使用 colClasses 强制列类型。

编码与 locale 问题

如果出现乱码:

# readr
df <- read_csv("file.csv", locale = locale(encoding = "latin1"))

# base read.table
df <- read.table("file.txt", fileEncoding = "UTF-8")

使用 Encoding() 检查,必要时用 iconv() 转换。

常见导入陷阱与故障排查

  • 标题错位 / 注释行: 使用 skip = ncomment = "#", 或 skip_empty_rows = TRUE
  • 列类型不一致: 预先指定列类型(col_typescolClasses)。
  • NA 标记: 设置 na = c("", "NA", "n/a")
  • 千位分隔符 / 小数点: locale = locale(decimal_mark = ",", grouping_mark = ".")
  • 内存错误: 在 SQL 端过滤,加载子集,或使用 Arrow/Parquet 只读取所需列。

快速技巧与生产力小窍门

  • 剪贴板导入(Windows/Mac):

    df <- read.table("clipboard", header = TRUE, sep = "\t")
  • 在完整导入前先预览前几行:

    readr::read_lines("file.csv", n_max = 10)
  • 读取后检查 readr 的解析问题:

    problems()
Back to Blog

相关文章

阅读更多 »