考虑这个简单的 RCurl
函数来报告下载进度:
library(RCurl)
curlDown=function(url, follow=TRUE){
x=getURL(url, followlocation=follow, noprogress = FALSE,
progressfunction=function(down,up) cat(down, '\n'))
}
请注意,使用 followlocation=TRUE
(默认)我们接受跟随服务器作为 HTTP header 的一部分发送的可能的重定向位置。
我们得到:
curlDown("http://www.example.com")
# 0 0
# 1270 1079
# 1270 1127
# 1270 1270
# 1270 1270
# 1270 1270
如您所见,RCurl
传递给回调的 down
变量是一个数值向量,其中第一个元素是以字节为单位的总下载量,第二个是运行下载大小。限于篇幅,这里就不展示了,单独查看发现前者相当于响应头中的Content-Length
字段。
并非每个服务器都在响应 header 中提供 Content-Length
字段:
curlDown("http://www.google.it")
# 0 0
# 0 603
# ... blah blah
# 0 44848
# 0 44848
在这种情况下,RCurl
将缺失的总值设置为零(NA
会更好吗?)。
Google 主域“.com”重定向到特定国家/地区的域,例如“.it”,如果您从与该域关联的国家/地区(意大利)进行查询。如果您实际位于“.it”域中,您将获得:
curlDown("http://www.google.com")
# 0 0
# 274 274
# 274 274
# 274 274
# 274 0
# 274 0
# 274 603
# ... blah blah
# 274 44896
# 274 44896
这些结果很奇怪。如果将正在运行的下载值与之前的 curlDown("http://www.google.it")
进行比较,您就会明白,在重定向之后,这些值与您预期的一样;但总数小于正在运行的下载量!
要了解我们不遵循重定向位置的问题:
curlDown("http://www.google.com", follow=FALSE)
# 0 0
# 274 274
# 274 274
# 274 274
主域服务器 .com
发送 Content-Length
,274 字节,而重定向服务器则不发送(参见 curlDown("http ://www.google.it"
).
问题是,在重定向之后,RCurl
不会更新总下载大小的值(对于未知大小的情况为零),它仍然堆叠为 274 字节的错误值.
这是 BUG 还是我遗漏了什么?
最佳答案
我认为 Rcurl 忠实地转发来自 curl 的值,例如,如在 CURLOPT_PROGRESSFUNCTION 下的 curl_set_easyopt 上记录的那样,缺失值返回为 0。如果有错误,那么它就是 curl。这是一个简单的程序(请参阅 here 开始)
#include <stdio.h>
#include <curl/curl.h>
curl_progress_callback progress(void *clientp, double dltotal, double dlnow,
double ultotal, double ulnow)
{
fprintf(stderr, "PROGRESS: %.0f %.0f %.0f %.0f\n",
dltotal, dlnow, ultotal, ulnow);
return 0;
}
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return 0;
}
它的评价
$ clang curl.c -lcurl && ./a.out http://google.com > /dev/null
PROGRESS: 0 0 0 0
PROGRESS: 0 0 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 219 0 0
PROGRESS: 219 0 0 0
PROGRESS: 219 2097 0 0
PROGRESS: 219 6441 0 0
PROGRESS: 219 12233 0 0
PROGRESS: 219 20921 0 0
PROGRESS: 219 32505 0 0
PROGRESS: 219 45360 0 0
PROGRESS: 219 45360 0 0
PROGRESS: 219 45360 0 0
关于r - 带有 URL 重定向的未记录的 RCurl "progressfunction",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21969948/