如何用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
相关产品推荐
相关产品推荐

