uncategorized

透過HttpWebRequest取得網頁內容

資料來源取得除了讀取DB內的資訊外,有時候也需要爬網頁的資訊取得,畢竟,有些資料不屬於自己控管,就必須透過這樣方式取得資料。

因此,在C#中可以透過HttpWebRequest方式去獲取網頁資料,再將資訊分析出來,取得屬於自己所要的資訊。大多數的網頁,都可以透過HTTP獲取,所以,透過HttpWebRequest提供WebRequest類別的HTTP 特定實作方式

使用HttpWebRequest,我們需要先初始化一個WebRequest類別,MSDN說明如下:

WebRequest 是從網際網路存取資料的 .NET Framework 要求/回應模型的 abstract 基底類別。 使用要求/回應模型的應用程式可以用不驗證通訊協定 (Protocol) 的方式,從網際網路要求資料,其中應用程式和 WebRequest 類別的執行個體 (Instance) 一起作用,而特定通訊協定的子代 (Descendant) 類別會完成要求的細節。

創建WebRequest物件


  1. 創建一個WebRequest物件

    1
    WebRequest myWebRequest = WebRequest.Create("Http://google.com");
  2. 設定呼叫時候的Timeout時間,這邊時間點是以毫秒為單位

    1
    myWebRequest.Timeout=10000;
  3. 在公司或是需要認證的才有辦法獲取的網頁地方,需要增加認證的帳號密碼與Domain Name

    1
    myWebRequest.Credentials = new NetworkCredential("Name", "PWD", "Domain Name");
  4. 若是需要透過proxy,也須設定proxy。在proxy設定中,我們可以設定proxy跟不需要透過proxy的IP List或是host name,或是在local端判定是否需要通過Proxy

    1
    myWebRequest.Proxy = new WebProxy(new Uri("http://proxy.hinet.net:8080"), true, strByPassIP);

    strByPassIP是屬於陣列型態。其設定如下,主要針對192.168.XX.XX及172.17.XX.XX網段不需要走Proxy

    1
    string[] strByPass = new string[] { @"192.\.168\..*", @"172\.17\..*" };

    若是指定IP則方式如下:

    1
    string[] strByPass = new string[] { "192.1.1.1", "192.2.2.2" };
  5. 基於安全性考量,有些Proxy也會需要指定帳號密碼與Domain Name(公司內部),此時也需要設定通過Proxy之帳號密碼

    1
    myWebRequest.Proxy.Credentials = new NetworkCredential("Name", "PWD", "Domain Name");

以上簡單幾個步驟就可以設定好WebRequest物件相關屬性
完整的Code如下:

1
2
3
4
5
6
7
8
9
internal static WebRequest CreateWebRequest()
{
WebRequest myWebRequest = WebRequest.Create("Http://google.com");
myWebRequest.Timeout=10000;
myWebRequest.Credentials = new NetworkCredential("Name", "PWD", "Domain Name");
myWebRequest.Proxy = new WebProxy(new Uri("http://proxy.hinet.net:8080"), true, strByPassIP);
myWebRequest.Proxy.Credentials = new NetworkCredential("Name", "PWD", "Domain Name");
return myWebRequest
}

設定HttpWebRequest相關屬性


再來就是定義HttpWebRequest取得網頁字串相關方式

1
HttpWebRequest myHttpWebRequest = (HttpWebRequest)(CreateWebRequest("Http://google.com"));

  1. 設定Timeout時間,這邊時間點是以毫秒為單位

    1
    myHttpWebRequest.Timeout =10000
  2. 設定取得網頁方式

    1
    myHttpWebRequest.Method="GET"
  3. 設定用戶端瀏覽器的原始使用者代理字串

    1
    myHttpWebRequest.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Windows NT 5.2; Windows NT 6.0; Windows NT 6.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 4.0C; .NET CLR 4.0E)"

以上屬性設定好之後,透過WebResponse物件,取得回傳的response資訊

1
WebResponse myWebResponse = myHttpWebRequest.GetResponse()

雖然,網頁都是文字型態,抓取網頁時還是必須要用資料流方式取的相關資訊。因此,我們需要透過GetResponseStream接收傳回來的網際網路資源的資料流,若是只單純當作字串接收,將會出現錯誤。

1
2
3
4
5
6
7
using (Stream myStream = myWebResponse.GetResponseStream())
{
using (StreamReader myStreamReader = new StreamReader(myStream)
{
string strHtml = myStreamReader.ReadToEnd();
}
}

以上方式將可以取得網頁內容回傳的資訊。
完整的Code如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string strHtml = string.Empty;
HttpWebRequest myHttpWebRequest = (HttpWebRequest)(CreateWebRequest(_strUrl));
myHttpWebRequest.Timeout =10000;
myHttpWebRequest.Method="GET";
myHttpWebRequest.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Windows NT 5.2; Windows NT 6.0; Windows NT 6.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 4.0C; .NET CLR 4.0E)";
using (WebResponse myWebResponse = myHttpWebRequest.GetResponse())
{
using (Stream myStream = myWebResponse.GetResponseStream())
{
using (StreamReader myStreamReader = new StreamReader(myStream)
{
strHtml = myStreamReader.ReadToEnd();
}
}
}