3

如何使用 Matlab 从 StackExchange API 访问数据?

天真的

sitedata = urlread('http://api.stackoverflow.com/1.1/questions?tagged=matlab')

由于数据被压缩而失败。但是,当我将其写入文件时(使用fprintf(fileID,'%s',sitedata)),我得到一个无法解压缩的 zip 文件。

4

2 回答 2

5

请尝试urlwrite()

urlwrite('http://api.stackoverflow.com/1.1/questions?tagged=matlab',...
  'tempfile.zip')
gunzip('tempfile.zip')
fid = fopen('tempfile');
str = textscan(fid,'%s',Delimiter','\n');
fclose(fid);

此代码段的更好版本将用于tempname动态生成临时文件名。

于 2013-01-10T00:20:08.060 回答
3

Matlaburlread假设您正在获取文本数据,而不是二进制数据。urlread当将字符数据解码为 Unicode 值以粘贴在 Matlabchar中时,或者当格式化输出fprintf函数将它们写出,将它们编码为 UTF-8 或您正在使用的任何默认字符编码时,gzip 二进制数据会被破坏和fileID改变字节序列,或者两者兼而有之。

IIRC,urlread将默认使用 ISO-8859-1 编码,这意味着字节将被转换为具有相同数值的 Unicode 代码点 - 实际上只是扩大。所以你可以通过做sitebytes = uint8(sitedata). (这是常规uint8()转换,而不是typecast()。)(如果不是这种情况,您可能可以摆弄urlread'CharSet选项。)

如果您无法urlread通过摆弄编码和强制转换来获取正确的字节,那么您可以HttpAgent像这样urlread做一样对Java进行调用并绕过字符集解码步骤,或者摆弄它的选项。请参阅urlread源代码以了解如何执行此操作。

一旦您在内存中拥有正确的字节,您就可以使用较低级别的函数将它们写入文件fwrite(),该函数不会通过执行字符集编码来破坏它们。然后,您将获得该站点原始响应的有效 gzip 文件。(我认为如果您也fwrite(fileID, sitedata, 'uint8')直接在 char 字符串上使用它会起作用,但恕我直言,它更丑陋。)

您还可以使用 Java 类将其解压缩到内存中并保存到文件系统的行程。jsitebytes = typecast(sitebytes 'int8')将它们作为 Java 友好的有符号字节获取,然后将其粘贴到 a中ByteArrayInputStream并通过GZIPInputStream. 您需要构建一个小的 Java 帮助程序类,因为 Matlab 在byte[]通过引用传递缓冲区方面表现不佳java.io,但如果您像这样进行大量内存中的处理,这可能是值得的。

在使用 Web 服务或更高级的数据下载(例如,需要会话或证书的站点)时,我经常会在 Matlab 中直接对HttpAgent和类进行编码。java.io

于 2013-01-10T08:49:07.893 回答