我通过last.fm的API为我的mashup获取大量用户数据。我每周都这样做,因为我必须收集收听数据。
我通过REST API和XML获取数据:更具体地说是simplexml_load_file()
。
脚本花了很长时间。对于大约2 300个用户,该脚本需要30分钟才能获取艺术家的名字。我现在必须解决它,否则我的托管公司将关闭我。我已经抽出了所有其他选项,正是XML正在减慢脚本。
我现在必须弄清楚last.fm是否有一个缓慢的API(或者在没有他们告诉我们的情况下限制调用),或者PHP的simplexml是否实际上相当慢。
我意识到的一件事是XML请求比我需要的要多得多,但我无法通过API限制它(即只给我3个波段的信息,而不是70个)。但“大”XML文件只能达到大约20kb。可能是这样,这会减慢脚本的速度吗?必须为2300个用户中的每一个加载20kb的对象?
没有意义,它可能是......我只需要确认它可能是last.fm的慢API。或者是吗?
您可以提供其他任何帮助吗?
答案 0 :(得分:1)
我不认为简单的xml是那么慢,它很慢,因为它是一个解析器,但我认为2300 curl / file_get_contents需要花费更多的时间。另外为什么不获取数据并只使用simplexml_load_string,你真的需要将这些文件放在服务器的磁盘上吗?
至少从内存加载应该加快一些事情,你还在加载的xmls上进行什么样的处理?你确定你的处理效率是多少吗?
答案 1 :(得分:1)
20kb * 2300用户约为45MB。如果你以~25kB /秒的速度下载,下载数据需要30分钟,更不用解析了。
答案 2 :(得分:0)
确保从last.fm下载的XML是gzip压缩的。您可能必须包含正确的HTTP标头以告知服务器您支持gzip。它会加快下载速度,但使用ungzipping部分会占用更多服务器资源。
还考虑使用异步下载来释放服务器资源。它不一定会加快进程,但它应该让服务器管理员满意。
如果XML本身很大,请使用SAX解析器,而不是DOM解析器。
答案 3 :(得分:0)
我认为每秒有一次API调用限制。我不确定这个策略是通过代码强制执行的,但它可能与它有关。如果您认为是这种情况,可以在irc.last.fm #audioscrobbler上询问IRC上的Last.fm工作人员。
答案 4 :(得分:0)
根据建议,使用simplexml_load_string
获取数据并进行解析,而不是依赖simplexml_load_file
- 它的速度大约是原来的两倍。这是一些代码:
function simplexml_load_file2($url, $timeout = 30) {
// parse domain etc from url
$url_parts = parse_url($url);
if(!$url_parts || !array_key_exists('host', $url_parts)) return false;
$fp = fsockopen($url_parts['host'], 80, $errno, $errstr, $timeout);
if($fp)
{
$path = array_key_exists('path', $url_parts) ? $url_parts['path'] : '/';
if(array_key_exists('query', $url_parts))
{
$path .= '?' . $url_parts['query'];
}
// make request
$out = "GET $path HTTP/1.1\r\n";
$out .= "Host: " . $url_parts['host'] . "\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
// get response
$resp = "";
while (!feof($fp))
{
$resp .= fgets($fp, 128);
}
fclose($fp);
$parts = explode("\r\n\r\n", $resp);
$headers = array_shift($parts);
$status_regex = "/HTTP\/1\.\d\s(\d+)/";
if(preg_match($status_regex, $headers, $matches) && $matches[1] == 200)
{
$xml = join("\r\n\r\n", $parts);
return @simplexml_load_string($xml);
}
}
return false; }