在 Cpp 中从 URL 下载时获取空 CSV

Getting an empty CSV when downloading from URL in Cpp

我的目标是使用 Cpp 从特定 URL 获取 CSV 或 XLS。

打开以下时link

http://www.centrodeinformacao.ren.pt/userControls/GetExcel.aspx?T=CRG&P=01-01-2007&variation=PT

,可以在浏览器工具中看到

一个 302 重定向和实际从下面下载的文件 URL

http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=02-01-2007&variation=PT

如下图所示(请求URL)

如果我手动转到两个 link 中的任何一个,.xls 文件下载得很好,所以我们不妨使用重定向后的文件。


我决定继续使用 libcurl with Visual Studio 2017 on my W10 machine. The recommended way to include libcurl in a Visual Studio 2017 project is to use vcpkg,这就是我使用的。


1。安装 vcpkg

  1. 打开GitBash,cd C:/Program Files/并克隆this repo

  1. 打开命令提示符,cd C:/Program Files/vcpkg, 运行 bootstrap-vcpkg.bat

及运行之后vcpkg integrate install


2。安装 libcurl

  1. 运行vcpkg install curl


3。创建一个新项目

  1. 简单地创建 Visual C++ > Windows 桌面 > Windows 控制台应用程序

能够立即使用#include <curl/curl.h>


4。当前结果

然后,在下面的回答中得到启发

并使用以下代码

#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}

void downloadFile(const char* url, const char* fname) {
    CURL *curl;
    FILE *fp;
    CURLcode res;
    curl = curl_easy_init();
    if (curl) {
        fp = fopen(fname, "wb");
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        fclose(fp);
    }
}

int main(void) {

    downloadFile("http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=01-01-2007&variation=PT", "C:\Users\molecoder\Desktop\test.csv");

}

我可以在所需文件夹中看到一个 test.csv,但它是一个空文件。

你必须了解你的 shell 是如何工作的。

注意:当您使用system()时,执行命令的是shell。

您的命令:

http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=01-01-2007&variation=PT

您的 shell 将“&”字符视为“与”运算符。将“与”的左右两边作为命令执行。所以它将以上内容视为三个命令:

http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG
P=01-01-2007
variation=PT

第二个命令失败P=01-01-2007

要解决此问题,您可能需要引用字符串。

"http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=01-01-2007&variation=PT"

 op.insert(0, 1, '"');
 op.append(1, '"');
 system(op.c_str());

转到特定 URL 后,将下载一个 .xls 文件。我不介意获取 XLS 而不是 CSV,因此将其更改为我能够按预期获取文件。

downloadFile("http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=01-01-2007&variation=PT", "C:\Users\molecoder\Desktop\test.xls");

这是最终代码

#include "pch.h"
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}

void downloadFile(const char* url, const char* fname) {
    CURL *curl;
    FILE *fp;
    CURLcode res;
    curl = curl_easy_init();
    if (curl) {
        fp = fopen(fname, "wb");
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        fclose(fp);
    }
}

int main(void) {

    downloadFile("http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG&P=01-01-2007&variation=PT", "C:\Users\molecoder\Desktop\test.xls");

}