Получение пустого CSV при загрузке с URL в Cpp - PullRequest
1 голос
/ 11 июля 2020

Моя цель - получить CSV или XLS из указанного c URL, используя Cpp.

При открытии следующей ссылки

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

можно увидеть в инструментах браузера

Browser redirect

a 302 redirect and the file being actually downloaded from the following URL

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

as shown in the next image (Request URL)

Request URL

If I go to any of the two links manually, the a .xls file downloads just fine so we might as well use the one after redirection.


I've decided to move on an use libcurl с Visual Studio 2017 на моем компьютере W10. Рекомендуемый способ включения libcurl в проект Visual Studio 2017 - использовать vcpkg , что я и использовал.

1. Установите vcpkg

  1. Откройте Git Bash, cd C: / Program Files / и клонируйте это репо .

Clone repo

  1. Открыть командную строку, cd C: / Program Files / vcpkg, запустить bootstrap-vcpkg.bat

bootstrap-vcpkg.bat

and after run vcpkg integrate install

vcpkg integrate install


2. Install libcurl

  1. Run vcpkg install curl

vcpkg install curl


3. Create a new project

  1. Simply create Visual C++ > Windows Desktop > Windows Console Application

Windows Console Application

to be able to use #include right away

image" />


4. Current Result

Then, inspired in the following answers

И используя следующий код

#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 в нужной папке, но это пустой файл.

пустой CSV

Ответы [ 2 ]

1 голос
/ 13 июля 2020

После перехода по указанному c 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");

}
0 голосов
/ 11 июля 2020

Вы должны понимать, как работает ваша оболочка.

Примечание: когда вы используете system(), именно оболочка выполняет команду.

Ваша команда:

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

Ваша оболочка обрабатывает символ «&» как оператор «и». Выполните левую и правую часть "и" как команды. Таким образом, он обрабатывает вышеуказанное как три команды:

http://www.centrodeinformacao.ren.pt/_layouts/CI.GetExcel/SafeGetExcel.aspx?T=CRG Р = 01-01-2007 вариация = 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());
...