Скачать файл по динамически сгенерированной ссылке, которая находится в исходном коде HTML

Я пытаюсь получить данные о погоде из BOM Australia. Ручной способ — перейти на http://www.bom.gov.au/jsp/ncc/cdio/weatherData/av?p_nccObsCode=136&p_display_type=dailyDataFile&p_startYear=&p_c=&p_stn_num=2064 и щелкните "Данные за все годы", и скачивает файл!

Вот что я пытался автоматизировать:

using (WebClient client = new WebClient())
            {

                string html = client.DownloadString("http://www.bom.gov.au/jsp/ncc/cdio/weatherData/av?p_nccObsCode=136&p_display_type=dailyDataFile&p_startYear=&p_c=&p_stn_num=2064");


                List<string> list = LinkExtractor.Extract(html);
                foreach (var link in list)
                {
                    if (link.StartsWith("/jsp/ncc/cdio/weatherData/av?p_display_type=dailyZippedDataFile"))
                    {

                        string resource = "http://www.bom.gov.au" + link;
                        MessageBox.Show(resource);


                        client.DownloadFileAsync(new Uri(resource), Dts.Connections["data.zip"].ConnectionString);
                        break;
                    }
                }




            }

Не беспокойтесь о linkExtractor, он работает, так как я могу видеть ссылку, которая дает файл. Проблема в том, что «DownloadFileAsync» создает новый запрос, который не позволяет загрузить файл, поскольку файлу требуется тот же сеанс.

Есть ли способ сделать это? Пожалуйста, обратитесь за дополнительными разъяснениями.

ОБНОВИТЬ:

Вот изменения, которые я сделал, используя файлы cookie из HttpWebRequest. Однако я все еще не могу скачать файл.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.bom.gov.au/jsp/ncc/cdio/weatherData/av?p_nccObsCode=136&p_display_type=dailyDataFile&p_startYear=&p_c=&p_stn_num=2064");
            request.CookieContainer = new CookieContainer();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            foreach (Cookie cook in response.Cookies)
            {
                MessageBox.Show(cook.ToString());
            }

            if (response.StatusCode == HttpStatusCode.OK)
           {
                Stream receiveStream = response.GetResponseStream();
                StreamReader readStream = null;

                if (response.CharacterSet == null)
                {
                    readStream = new StreamReader(receiveStream);
                }
                else
                {
                    readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
                }

                string data = readStream.ReadToEnd();



                using (WebClient client = new WebClient())
                {
                    foreach (Cookie cook in response.Cookies)
                    {
                        MessageBox.Show(cook.ToString());
                        client.Headers.Add(HttpRequestHeader.Cookie, cook.ToString());
                    }

                    List<string> list = LinkExtractor.Extract(data);
                    foreach (var link in list)
                    {
                        if (link.StartsWith("/jsp/ncc/cdio/weatherData/av?p_display_type=dailyZippedDataFile"))
                        {

                            string initial = "http://www.bom.gov.au" + link;
                            MessageBox.Show(initial);

                            //client.Headers.Add(HttpRequestHeader.Cookie, "JSESSIONID=2EBAFF7EFE2EEFE8140118CE5170B8F6");
                            client.DownloadFile(new Uri(initial), Dts.Connections["data.zip"].ConnectionString);
                            break;
                        }
                    }




                }

                response.Close();
                readStream.Close();
            }

person Vikas Dhochak    schedule 10.08.2016    source источник
comment
Не могли бы вы уточнить, как использование файлов cookie может помочь, поскольку для просмотра веб-сайта не требуются учетные данные пользователя?   -  person Vikas Dhochak    schedule 11.08.2016
comment
Потому что некоторые сайты заботятся о своем контенте и принимают меры для предотвращения легкого парсинга. Некоторым может потребоваться файл cookie сеанса, некоторые генерируют уникальные URL-адреса при каждом GET, некоторым нужен реферер, некоторые запускают javascript и выполняют пару запросов ajax. Если вы можете успешно загрузить файл с помощью браузера, вам нужно только имитировать это. Веб-клиент не собирается делать это самостоятельно. Используйте консоль разработчика вашего браузера, чтобы выяснить, что необходимо в последующих HTTP-вызовах.   -  person rene    schedule 11.08.2016
comment
Консоль показывает это, когда я нажимаю, чтобы загрузить файл: Ресурс интерпретируется как документ, но передается с помощью приложения/zip типа MIME: bom.gov.au/jsp/ncc/cdio/weatherData/.   -  person Vikas Dhochak    schedule 11.08.2016
comment
Нужно смотреть вкладку сети и изучать заголовки запроса и ответа...   -  person rene    schedule 11.08.2016
comment
Я могу видеть файл cookie запроса. Как установить файл cookie запроса из первой ссылки в качестве файла cookie запроса для второй ссылки. Пример «CookieAwareWebClient» у меня не работает   -  person Vikas Dhochak    schedule 11.08.2016
comment
Давайте продолжим обсуждение в чате.   -  person Vikas Dhochak    schedule 11.08.2016


Ответы (1)


HTML-код, который вы получаете, и URL-адрес внутри него являются HtmlEncoded. Это означает, что когда вы подстроите URL-адрес из html, вам нужно его декодировать, в идеале. Вот как выглядит URL-адрес загрузки для zip:

   /jsp/ncc/cdio/weatherData/av?p_display_type=dailyZippedDataFile&amp;p_stn_num=2064&amp;p_c=-938623&amp;p_nccObsCode=136&amp;p_startYear=2016

Существует вспомогательный класс для декодирования: WebUtility

Этот код загружает zip-файл:

using (var client = new WebClient())
{
    var url = "http://www.bom.gov.au/jsp/ncc/cdio/weatherData/av?p_nccObsCode=136&p_display_type=dailyDataFile&p_startYear=&p_c=&p_stn_num=2064";    
    string html = client.DownloadString(url);

    var pos = html.IndexOf("/jsp/ncc/cdio/weatherData/av?p_display_type=dailyZippedDataFile");
    var endpos = html.IndexOf('"', pos);
    string link = html.Substring(pos, endpos - pos);

    var decodedLink = WebUtility.HtmlDecode(link);
    string resource = "http://www.bom.gov.au" + decodedLink;                    


    client.DownloadFile(new Uri(resource), @"c:\temp\bom2.zip");

}

В этом случае вам не нужно сохранять файлы cookie, но вам нужно быть осторожным с URL-адресами, которые вы анализируете.

person rene    schedule 11.08.2016