c# Скрипт для входа и загрузки с Kaggle

Недавно я наткнулся на скрипт Python для загрузки файлов напрямую из Kaggle: https://ramhiser.com/2012/11/23/how-to-download-kaggle-data-with-python-and-request-dot-py/

Я пытаюсь сделать что-то подобное, используя WebClients в С#. Я получил следующий ответ в StackOverFlow: С# загрузить файл из Интернет с логином

Пытался использовать его, но, похоже, я загружаю только страницу входа вместо фактического файла. Вот мой основной код:

CookieContainer cookieJar = new CookieContainer();
CookieAwareWebClient http = new CookieAwareWebClient(cookieJar);

string postData = "name=<username>&password=<password>&submit=submit";
string response = http.UploadString("https://www.kaggle.com/account/login", postData);
Console.Write(response);

http.DownloadFile("https://www.kaggle.com/c/titanic/download/train.csv", "train.CSV");

Я использовал расширение Webclient по ссылке выше и немного изменил:

public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; }
    public Uri Uri { get; set; }

    public CookieAwareWebClient()
        : this(new CookieContainer())
    {
    }

    public CookieAwareWebClient(CookieContainer cookies)
    {
        this.CookieContainer = cookies;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        this.Uri = address;
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = this.CookieContainer;
        }
        HttpWebRequest httpRequest = (HttpWebRequest)request;
        httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        return httpRequest;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse r = base.GetWebResponse(request);
        var response = r as HttpWebResponse;
        if (response != null)
        {
            CookieCollection cookies = response.Cookies;
            CookieContainer.Add(cookies);
        }
        return response;
    }
}

Интересно, может ли кто-нибудь указать, где я ошибся?

Спасибо.


person Jeremy Loh    schedule 13.03.2018    source источник


Ответы (3)


Мы создали сообщение на форуме, чтобы помочь вам выполнить то, что вы хотели сделать, Доступ к Kaggle API через C#. Не стесняйтесь писать здесь или на форуме, если у вас есть дополнительные вопросы.

person Peijen    schedule 15.03.2018
comment
Hei Peijen, спасибо за обновление. Когда я пытался использовать предоставленный пример кода, я, кажется, загружал файлы со следующим содержимым: только System.Net.Http.WinHttpResponseStream. Это происходит со всеми файлами, и я пробовал как с проектом в примере кода, так и с печально известным проектом Титаник. Вы знаете, почему это происходит? ps: я пробовал использовать как .Net framework, так и .Net core, и результаты одинаковы. - person Jeremy Loh; 16.03.2018
comment
Джереми, я обновил код, чтобы использовать FileStream вместо StreamWriter, попробуйте и посмотрите, работает ли он. - person Peijen; 16.03.2018
comment
К сожалению, это не работает. У меня поток не поддерживает запись. Я тоже не могу установить положение. - person Jeremy Loh; 16.03.2018
comment
Вы использовали stream.CopyTo(output); Вместо output.Write(поток); Извините, что не назвал это в предыдущем комментарии. Если это все еще не работает, не могли бы вы опубликовать свой код где-нибудь, и я могу посмотреть. - person Peijen; 16.03.2018
comment
Ага, я это заметил. Вот ссылка на сам файл: drive.google.com/ file/d/1E3ryHnBDSGL-HoSBMQsOeGOBI8sd37aj/ В этом случае я в значительной степени скопировал и вставил js код, который у вас был в вашем образце. - person Jeremy Loh; 16.03.2018
comment
а, вам нужен поток.CopyTo(output), а не output.CopyTo(stream) - person Peijen; 16.03.2018
comment
гаах, не могу поверить, что пропустил это. Теперь работает. большое спасибо за твою помощь! - person Jeremy Loh; 17.03.2018

Попробуйте перейти на https://www.kaggle.com/c/titanic/download/train.csv в браузере без входа в систему, и ваш браузер откроет эту страницу вместо загрузки вашего файла. Вам нужно поставить прямую ссылку на файл вместо веб-страницы.

Ваш код работает отлично, вам просто нужно поставить прямую ссылку на этот файл или убедиться, что вы вошли в систему перед загрузкой файла.

person Red Wei    schedule 13.03.2018
comment
Эй, Рэд, да, ты прав, что для загрузки требуется вход в систему. Отсюда я понял, что вызывая этот метод http.UploadString(..), WebClientExtension входит в систему, сохраняет куки, чтобы в следующий раз, когда я попытаюсь получить доступ к странице или загрузить файл через http.DownloadFile(...), он использует файл cookie для доступа к прямой ссылке, но, похоже, это не работает для меня. - person Jeremy Loh; 14.03.2018
comment
Это string postData = "name=<username>&password=<password>&submit=submit";. Это не всегда имя и пароль, вам нужно просмотреть веб-куки и следовать их шаблону. Попробуйте string postData = "UserName=<username>&Password=<password> - person Red Wei; 14.03.2018
comment
Да, играл с ним, но не удалось пройти. Думаю, я попробую API и посмотрю, смогу ли я получить лучший результат. Спасибо, в любом случае. - person Jeremy Loh; 16.03.2018

Я знаю, что это не совсем то, о чем вы спрашивали, но Kaggle теперь имеет официальный API, который вы можете использовать для загрузки данных. Должно быть немного проще в использовании. :)

person Rachael Tatman    schedule 13.03.2018
comment
спасибо Рэйчел за информацию. Однако API доступен для python, пока я пытаюсь напрямую использовать С# для получения файлов. - person Jeremy Loh; 14.03.2018
comment
Ах, попался. Я не думаю, что есть какие-либо планы по выпуску C# API, но я передам это. - person Rachael Tatman; 15.03.2018