如何读取API下载的gzip文件?解压后无销售数据排查
问题
尝试调用Stone的API下载客户销售数据文件,初始代码如下:
url = URI("https://conciliation.stone.com.br/v1/merchant/{MYCODE}/conciliation-file/20240909") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["accept"] = 'application/xml' request["Authorization"] = 'Bearer USERID' request["X-Authorization-Raw-Data"] = 'ENCRIPTED STRING' request["X-Authorization-Encrypted-Data"] = 'TOKEN' request["Accept-Encoding"] = 'gzip' response = http.request(request) puts response.read_body
返回内容为gzip压缩后的二进制数据:
[3] pry(Stone)> response.read_body => "\x1F\x8B\b\x00\x00\x00\x00\x00\x04\x00}\x93\xCBN\x830\x10E\x7F\x05\xB1/\x06\xFA\b\x8D\x1CG\x15m\xDAJ]\xF4\x11u?\xC5\x93\xC4\xAA\xB1#l\xA2\xE4\xEFk\xC8\xA3@\b;k\xEE=3w\xC0\xA6\xD3m.\xBD\r\x16Fh5\xF1\xA3 \xF4=T\x99\xE6B-'~i\x17W\x89?e4\xD5*\x13R\x80u.\xCF\x11\xCA\x8C\xB7\x86O\xFC\x95\xB5\xEB1!&[a\x0E&0V+\f2\x9D\x13\x9F\xD1\x17\x04\x8E\x05\xA3\xCF\xA8\xB0\xA8\xC9G\xB08\x179\xB28\x8Co\xC2\xFB(\x8C\x92(\xBA\x8D)\xE9\xB1\xD0\xAF\xAAW\xAA9\xB2$\xBE\x8BF\xE1\xE8\xDA\x19\xFF\x8B\xF4\rv\xBA\xB4\xDF\xFB\xE4,\x0E\x9C\xDA.\xD1\x99\x90\xF8\xCAYH\xC9\xE1D?q\x81\x85[\x0F\xAB1\x87\x14aBI\xBBN\xC91\xFAL(p\x8B\x83\x9C\x17\xA0\fdUB\xE3\x91\x86\xF0\xB4Ae\xDB\xA5\xA6\xF7!\xCBt\xD95\xD4LSy\x87]~l\xE3h\x17\xD6\xCDNam\xCB\x02y\xB3\xDDG\t\xCA\n\xBB\xABv\x1A\xD4\x1D\xED\xB6\x91C\xF4\x80\xEE\x02\t\xFE\xAA\x8C\x05)\xEB`M\xF2\xA2F\xD3\x15\x14K\xE4\xFB\xD6\x12\xCEg\x0E\xE9\a\xFA\a\xB2\xDF\x1E\xA8]nz\xDD\xAF+\x15\xBF@t\xC4S\xC2\xA1Q\xBDj\xFDE\x06\xA7\x0E\ej~\x7FW\xBAP\xA7z\xCCxn\xEE\x17(9\xDD\x18\xD2|\xA5\xEC\x0F\xA7\x9FA\x1F\xDA\x03\x00\x00"
后续修改代码处理gzip解压:
if response['Content-Encoding'] == 'gzip' sio = StringIO.new(response.body) gz = Zlib::GzipReader.new(sio) decompressed_body = gz.read else decompressed_body = response.body end
代码运行正常,但解压后查询多日文件均显示无销售数据,实际数据是存在的,需解决该问题。
解决方案
验证请求参数准确性
- 替换
{MYCODE}为真实商户代码,检查拼写是否正确; - 确认日期格式是否符合API要求:部分API要求
YYYY-MM-DD格式,可尝试修改URL日期为2024-09-09测试; - 核对所有授权头信息:
Authorization、X-Authorization-Raw-Data、X-Authorization-Encrypted-Data的取值需完全正确,无过期或格式错误。
- 替换
完善解压逻辑与内容检查
- 解压后打印原始内容,确认是否为空或包含错误提示:
部分API会返回XML格式的错误信息(如权限不足、日期无效),直接解析可能误判为无数据;puts decompressed_body.inspect - 添加异常捕获,处理解压失败情况:
begin if response['Content-Encoding'] == 'gzip' sio = StringIO.new(response.body) gz = Zlib::GzipReader.new(sio) decompressed_body = gz.read gz.close else decompressed_body = response.body end rescue Zlib::Error => e puts "解压失败: #{e.message}" puts response.body.inspect end
- 解压后打印原始内容,确认是否为空或包含错误提示:
检查响应状态码
- 请求后打印响应状态码,判断请求是否成功:
若状态码不是puts response.code200 OK,需先解决请求本身的问题(如401授权失败、404资源不存在)。
- 请求后打印响应状态码,判断请求是否成功:
确认Accept头与返回格式匹配
- 当前
accept头为application/xml,可尝试改为application/octet-stream,直接保存文件到本地查看:
打开本地文件确认是否存在数据,避免因格式解析问题导致误判。request["accept"] = 'application/octet-stream' File.write('conciliation_data.xml', decompressed_body)
- 当前
内容的提问来源于stack exchange,提问作者Diogo Amaral
相关产品推荐
相关产品推荐

