2016-08-10 11 views
1

BOM 오스트레일리아에서 날씨 데이터를 가져 오려고합니다. 수동으로 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으로 이동하여 '모든 연도의 데이터'를 클릭하면 파일이 다운로드됩니다.HTML 소스 코드에있는 동적으로 생성 된 링크에서 파일 다운로드

여기에 내가 이것을 자동화하는 시도 내용은 다음과 같습니다

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'가 파일에 동일한 세션이 필요하기 때문에 파일을 다운로드 할 수 없도록하는 새 요청을 생성한다는 것입니다.

내가 할 수있는 방법이 있습니까? 더 자세한 설명을 위해 연락하십시오.

UPDATE :

는 다음의 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(); 
      } 
+0

웹 사이트를 탐색하는 데 필요한 사용자 자격 증명이 없으므로 쿠키 사용이 어떻게 도움이되는지 자세히 설명해 주실 수 있습니까? –

+0

일부 사이트는 콘텐츠에 신경을 쓰고 쉽게 긁히지 않도록 조치를 취하기 때문입니다. 어떤 것은 세션 쿠키를 필요로 할 수도 있고, 어떤 것은 각 GET에 대해 고유 한 URL을 생성하거나, 어떤 리퍼러가 필요하거나, 어떤 자바 스크립트를 실행하고, 몇 가지 아약스 요청을 할 수 있습니다. 브라우저로 파일을 성공적으로 다운로드 할 수 있다면 그 파일을 모방하면됩니다. 웹 클라이언트는 자체적으로 그렇게하지 않습니다. 브라우저의 개발자 콘솔을 사용하여 이후의 http 호출에 필요한 것을 파악합니다. – rene

+0

콘솔을 클릭하면 파일을 다운로드 할 수 있습니다 : 리소스는 문서로 해석되었지만 MIME 유형 application/zip으로 전송 된 리소스 : "http://www.bom.gov.au/jsp/ncc/cdio/weatherData/av ? p_display_type = dailyZippedDataFile & p_stn_num = 2064 & p_c = -938623 & p_nccObsCode = 136 & p_startYear = 2016 ". –

답변

2

당신이 얻는 HTML과 그 안에있는 URL은 HtmlEncoded입니다. 그렇게하면 html로 URL을 부분 문자열로 처리 할 때 이상적으로 디코딩해야합니다. WebUtility

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 

이 헬퍼 클래스는 우리를 위해 디코딩을 할 수있다 :이 같은 우편의 다운로드 URL이 모습입니다

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"); 

} 

쿠키를 보관할 필요는 없지만 구문 분석 한 URL을 신중히 사용해야합니다.

+0

젠장! 나는 심지어 그것을 알아 차리지 못했다. 고마워, 그거야. –