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

如何用R程序自动抓取SIPRI网站1990-2000年各国进口数据

自动获取SIPRI武器贸易进口数据问题

我需要从SIPRI武器贸易数据网站抓取数据,网站通过表单的单选按钮和下拉框提供时间范围、国家选择和下载方式。我知道可以手动下载,但希望用程序自动获取1990-2000年所有国家的进口数据,最终得到和手动下载的Excel结构一致的DataFrame。

我尝试了两种方法,但都没得到预期结果,代码如下:

方法1

参考了针对该网站的Python方案,代码如下:

library(httr)
library(rvest)
df = httr::POST("https://armstrade.sipri.org/armstrade/html/export_values.php", 
             encode = "form",
             body = list('import_or_export' = 'export',
                         'country_code'= 'All',
                         'from' = 1990,
                         'to' = 2000,
                         'summarize' = 'country',
                         'filetype'= 'excel',
                         'Action' ='Download'),
             verbose())

方法2

参考POST请求相关方案,代码如下:

headers = c('Content-Type' = 'application/json; charset=UTF-8')
data = "{'country_code':'All','low_year':'1990','high_year':'2000','import_or_export':'import','summarize':'country','filetype':'html','Action':'Download'}"
r <- httr::POST(url = "https://armstrade.sipri.org/armstrade/html/export_values.php", 
                httr::add_headers(.headers=headers), body = data)

修正后的解决方案

问题分析

  • 方法1的核心错误:import_or_export参数设为了export,但需求是进口数据,需改为import
  • 方法2的核心错误:网站表单采用application/x-www-form-urlencoded格式,而非JSON;参数名错误(应使用from/to而非low_year/high_year);JSON格式的字符串需用双引号而非单引号

正确代码

library(httr)
library(readxl)

# 发送POST请求获取Excel文件
response <- httr::POST(
  url = "https://armstrade.sipri.org/armstrade/html/export_values.php",
  encode = "form",  # 自动处理表单编码,无需手动设置Content-Type
  body = list(
    import_or_export = "import",
    country_code = "All",
    from = 1990,
    to = 2000,
    summarize = "country",
    filetype = "excel",
    Action = "Download"
  )
)

# 验证请求并读取数据
if (httr::http_status(response)$category == "Success") {
  # 创建临时文件存储Excel内容
  temp_file <- tempfile(fileext = ".xlsx")
  writeBin(httr::content(response, "raw"), temp_file)
  
  # 读取Excel转为DataFrame
  df <- readxl::read_excel(temp_file)
  
  # 清理临时文件
  file.remove(temp_file)
  
  # 查看数据结构
  print(head(df))
} else {
  stop("请求失败,状态码:", httr::status_code(response))
}

关键说明

  • 使用encode = "form"适配网站表单的编码格式,避免手动配置头部的错误
  • 直接请求Excel格式文件,通过readxl包读取后得到的DataFrame结构与手动下载的完全一致
  • 增加了请求状态验证,确保数据获取成功后再进行后续处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:07:49