Загрузите файл через HTTPS, используя .NET (часть 2) - PullRequest
0 голосов
/ 09 февраля 2010

На регулярной основе мне приходится делать следующее вручную в веб-браузере:

  1. Перейдите на веб-сайт https.
  2. Вход в веб-форму.
  3. Нажмите на ссылку, чтобы загрузить большой файл (135 МБ).

Я бы хотел автоматизировать этот процесс с помощью .NET.

Несколько дней назад я разместил этот вопрос здесь. Благодаря фрагменту кода Rubens Farias я теперь могу выполнять вышеуказанные шаги 1 и 2. После шага 2 я могу прочитать HTML-код страницы, содержащей URL-адрес загружаемого файла (используя afterLoginPage = reader .ReadToEnd ()). Эта страница отображается только в том случае, если вход в систему предоставлен, поэтому шаг 2 проверен на успешность.

Теперь у меня вопрос, как, конечно, как выполнить шаг 3. Я пробовал кое-что, но безрезультатно, доступ к файлу был закрыт, несмотря на успешный предыдущий вход в систему.

Чтобы прояснить ситуацию, я опубликую приведенный ниже код, разумеется, без фактической информации для входа и сайтов. В конце переменная afterLoginPage содержит HTML-код страницы после входа в систему, содержащей ссылку на файл, который я хотел бы загрузить. Эта ссылка также начинается с https.

Dim httpsSite As String = "https://www.test.test/user/login"
' enter correct address
Dim formPage As String = ""
Dim afterLoginPage As String = ""

' Get postback data and cookies
Dim cookies As New CookieContainer()
Dim getRequest As HttpWebRequest = DirectCast(WebRequest.Create(httpsSite), HttpWebRequest)
getRequest.CookieContainer = cookies
getRequest.Method = "GET"

Dim wp As WebProxy = New WebProxy("[our proxies IP address]", [our proxies port number])
wp.Credentials = CredentialCache.DefaultCredentials
getRequest.Proxy = wp

Dim form As HttpWebResponse = DirectCast(getRequest.GetResponse(), HttpWebResponse)
Using response As New StreamReader(form.GetResponseStream(), Encoding.UTF8)
    formPage = response.ReadToEnd()
End Using

Dim inputs As New Dictionary(Of String, String)()
inputs.Add("form_build_id", "[some code I'd like to keep secret]")
inputs.Add("form_id", "user_login")
For Each input As Match In Regex.Matches(formPage, "<input.*?name=""(?<name>.*?)"".*?(?:value=""(?<value>.*?)"".*?)? />", RegexOptions.IgnoreCase Or RegexOptions.ECMAScript)
    If input.Groups("name").Value <> "form_build_id" And _
       input.Groups("name").Value <> "form_id" Then
        inputs.Add(input.Groups("name").Value, input.Groups("value").Value)
    End If
Next

inputs("name") = "[our login name]"
inputs("pass") = "[our login password]"

Dim buffer As Byte() = Encoding.UTF8.GetBytes( _
[String].Join("&", _
Array.ConvertAll(Of KeyValuePair(Of String, String), String)(inputs.ToArray(), _
Function(item As KeyValuePair(Of String, String)) (item.Key & "=") + System.Web.HttpUtility.UrlEncode(item.Value))))

Dim postRequest As HttpWebRequest = DirectCast(WebRequest.Create(httpsSite), HttpWebRequest)
postRequest.CookieContainer = cookies
postRequest.Method = "POST"
postRequest.ContentType = "application/x-www-form-urlencoded"
postRequest.Proxy = wp

' send username/password
Using stream As Stream = postRequest.GetRequestStream()
    stream.Write(buffer, 0, buffer.Length)
End Using

' get response from login page
Using reader As New StreamReader(postRequest.GetResponse().GetResponseStream(), Encoding.UTF8)
    afterLoginPage = reader.ReadToEnd()
End Using

Ответы [ 4 ]

3 голосов
/ 09 февраля 2010

Как я уже сказал в комментариях к этому вопросу, вам просто нужно использовать метод DownloadFile:

using(WebClient client = new WebClient())
    client.DownloadFile(
        "http://www.google.com/", "google_homepage.html");

Просто замените "http://www.google.com/" на свой адрес файла.

Извините, вам нужно перейти с HttpWebRequest:

string fileAddress = "http://www.google.com/";
HttpWebRequest client = (HttpWebRequest)WebRequest.Create(fileAddress));
client.CookieContainer = cookies;
int read = 0;
byte[] buffer = new byte[1024];
using(FileStream download = 
  new FileStream("google_homepage.html", FileMode.Create))
{
    Stream stream = client.GetResponse().GetResponseStream();
    while((read = stream.Read(buffer, 0, buffer.Length)) != 0)
    {
        download.Write(buffer, 0, read);
    }
}
2 голосов
/ 09 февраля 2010

Передаете ли вы куки при загрузке файла?

1 голос
/ 09 февраля 2010

В качестве альтернативы вы можете выбрать автоматизацию Internet-Explorer вместо того, чтобы пытаться отправлять веб-запросы через HTTPS.
Веб-автоматизация с помощью Powershell объясняет это с помощью PowerShell, но вы также можете сделать это в C # при доступе к Internet Explorer как объект COM. Этот метод работает довольно хорошо, если вам нужен только один файл и не нужно бояться утечек памяти.

1 голос
/ 09 февраля 2010

Вам необходимо сохранить файл cookie сеанса / аутентификации, который будет отправлен вам обратно через форму входа. Обычно берут куки из ответа формы аутентификации и отправляют их обратно, когда вы делаете шаг 3.

Это простой способ расширить веб-клиент, который должен дать вам гораздо более простой код, чем приведенный выше:

http://couldbedone.blogspot.com/2007/08/webclient-handling-cookies.html

Всего:

  1. Создать экземпляр этого CookieAwareWebClient
  2. Разместить на форме авторизации
  3. Скачать файл
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...