Автоматическая загрузка файлов с использованием WebBrowser без URL - PullRequest
6 голосов
/ 18 июля 2009

Я работал над WebCrawler, написанным на C #, используя System.Windows.Forms.WebBrowser. Я пытаюсь загрузить файл с веб-сайта и сохранить его на локальном компьютере. Что еще более важно, я хотел бы, чтобы это было полностью автоматизировано. Загрузка файла может быть начата нажатием кнопки, которая вызывает функцию javascript, которая вызывает загрузку, отображая диалоговое окно «Хотите открыть или сохранить этот файл?». Я определенно не хочу вручную нажимать «Сохранить как» и вводить имя файла.

Мне известны функции загрузки HttpWebRequest и WebClient, но поскольку загрузка началась с использованием JavaScript, я теперь знаю URL-адрес файла. Кстати, javascript - это функция doPostBack, которая изменяет некоторые значения и отправляет форму.

Я попытался сосредоточиться на диалоге сохранения в WebBrowser, чтобы автоматизировать его без особого успеха. Я знаю, что есть способ заставить загрузку сохранить вместо запроса сохранения или открытия, добавив заголовок к запросу http, но я не знаю, как указать путь к файлу для загрузки.

Ответы [ 4 ]

5 голосов
/ 18 июля 2009

Я думаю, вы должны запретить показ диалога загрузки. Вот способ сделать это:

  • Код Javascript заставляет ваш элемент управления WebBrowser перейти к определенному URL-адресу (что может вызвать появление диалогового окна загрузки)

  • Чтобы не допустить фактической навигации элемента управления WebBrowser к этому URL, прикрепите обработчик события к событию Navigating.

  • В вашем событии Navigating вам нужно будет проанализировать, является ли это действительным действием Navigation, которое вы хотите прекратить (это URL-адрес загрузки, возможно, проверьте расширение файла, должен быть распознаваемый формат ). Для этого используйте WebBrowserNavigatingEventArgs.Url.

  • Если это правильный URL-адрес, остановите навигацию, установив свойство WebBrowserNavigatingEventArgs.Cancel.

  • Продолжите загрузку самостоятельно с помощью классов HttpWebRequest или WebClient

Загляните на эту страницу, чтобы узнать больше о событии:
http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.navigating.aspx

4 голосов
/ 18 августа 2010

Аналогичное решение доступно на http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/d338a2c8-96df-4cb0-b8be-c5fbdd7c9202/?prof=required

Это прекрасно работает, если есть прямой URL, включая загрузку имени файла.

Но иногда некоторые URL генерируют файл динамически. Таким образом, URL не имеет имени файла, но после запроса этого URL-адреса веб-сайт динамически создает файл, а затем открывается диалоговое окно открытия / сохранения.

например, какая-то ссылка создает файл PDF на лету.

Как обрабатывать URL-адреса такого типа?

1 голос
/ 10 мая 2016

Предполагается, что System.Windows.Forms.WebBrowswer использовался для доступа к защищенной странице с защищенной ссылкой, которую вы хотите загрузить:

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

var documentLinkUrl = default(Uri);
browser.DocumentCompleted += (object sender, WebBrowserDocumentCompletedEventArgs e) =>
{
    var aspForm = browser.Document.Forms[0];
    var downloadLink = browser.Document.ActiveElement
        .GetElementsByTagName("a").OfType<HtmlElement>()
        .Where(atag => 
            atag.GetAttribute("href").Contains("DownloadAttachment.aspx"))
        .First();

    var documentLinkString = downloadLink.GetAttribute("href");
   documentLinkUrl = new Uri(documentLinkString);
}
browser.Navigate(yourProtectedPage);

Теперь, когда защищенная страница была открыта веб-браузером и получена ссылка для загрузки, этот код загружает ссылку.

private static async Task DownloadLinkAsync(Uri documentLinkUrl)
{
    var cookieString = GetGlobalCookies(documentLinkUrl.AbsoluteUri);
    var cookieContainer = new CookieContainer();
    using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
    using (var client = new HttpClient(handler) { BaseAddress = documentLinkUrl })
    {
        cookieContainer.SetCookies(this.documentLinkUrl, cookieString);
        var response = await client.GetAsync(documentLinkUrl);
        if (response.IsSuccessStatusCode)
        {
            var responseAsString = await response.Content.ReadAsStreamAsync();
            // Response can be saved from Stream

        }
    }
}

Приведенный выше код опирается на метод GetGlobalCookies от Эрики Чинчио, который можно найти в отличной статье, предоставленной @Pedro Leonardo (доступно здесь ),

[System.Runtime.InteropServices.DllImport("wininet.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
static extern bool InternetGetCookieEx(string pchURL, string pchCookieName,
    System.Text.StringBuilder pchCookieData, ref uint pcchCookieData, int dwFlags, IntPtr lpReserved);

const int INTERNET_COOKIE_HTTPONLY = 0x00002000;

private string GetGlobalCookies(string uri)
{
    uint uiDataSize = 2048;
    var sbCookieData = new System.Text.StringBuilder((int)uiDataSize);
    if (InternetGetCookieEx(uri, null, sbCookieData, ref uiDataSize,
            INTERNET_COOKIE_HTTPONLY, IntPtr.Zero)
        &&
        sbCookieData.Length > 0)
    {
        return sbCookieData.ToString().Replace(";", ",");
    }
    return null;
}
1 голос
/ 18 сентября 2015

Взгляните на статью Эрики Чинчио на http://www.codeproject.com/Tips/659004/Download-of-file-with-open-save-dialog-box

Я успешно использовал его для загрузки динамически сгенерированных PDF-файлов.

...