2012-12-05

[ASP.NET] 使用HttpWebRequest取得 Facebook Open Graph META tags

本範例使用 WebRequest 取得 指定網站的 HTML 編碼,並使用規則運算取得篩出 Facebook Open Graph META Tags 資料。

使弿 WebRequest 建立 HttpWebRequest 物件,設定 Timeout 為 10 秒。 使用GetResponse() 方法將server回應的資料暫時轉成 utf-8 編碼格式,並使用規則運算取得網頁編碼,判斷是否為 utf-8,否則重新取得串流並轉成網頁編碼,必免出現亂碼問題。

    // HtmlCaptureManage.cs 
    
    /// < summary> 取得 html Data </summary>
    /// < param name="url"> 指定網址 </param>
    private void GetHtml(string url)
    {
     string html;
     
     // 建立 WebRequest 
     HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
     request.Timeout = 10000;
     
     HttpWebResponse response = request.GetResponse() as HttpWebResponse;
     
     // 取得 server 回傳的串流
     StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"));
     html = sr.ReadToEnd();
     
     // 取得 網頁編碼
     string charset = "(?<=charset=)[^;,\r\n\"']*";
     Regex regEncoder = new Regex(charset);
     string cType = regEncoder.Match(html).Value;
     
     // 判斷是否為 預設的 編碼,否重新載入
     if (cType != "utf-8" && cType != "")
     {
      response.Close();
      sr.Close();
      request = WebRequest.Create(url) as HttpWebRequest;
      sr = new StreamReader(request.GetResponse().GetResponseStream(), System.Text.Encoding.GetEncoding(cType));
      html = sr.ReadToEnd();
     }
     
     HtmlContext = html;
    }
   

使用 Regex 物件 設定其條件,使用 Match()方法 ,篩出符合條件的資料,圓傳值為 Match。

    // YouTubeHtmlCapture.cs
    
    // 檽得 og:title
    string title = "(?<=\\Wog:title\\W.content=\\W)(?<text>[^;,\r\n\"]*)";
    
    // 檽得 og:description
    string description = "(?<=\\Wdescription\\W.content=\\W)(?<text>[^;,\r\n\"]*)";
    
    // 檽得 og:video
    string video = "(?<=\\Wog:video\\W.content=\\W)(?<text>[^,\r\n\"]*)";
    
    // 檽得 og:url
    string url = "(?<=\\Wog:url\\W.content=\\W)(?<text>[^;,\r\n\"]*)";
    
    // 檽得 符合條件之參數 (條件1: http, 條件2: .ico)
    string icon = "(https?:)?//?[^'\"<>\n]+?\\.(ico)";
    
    // 檽得 og:image
    string image = "(?<=\\Wog:image\\W.content=\\W)(?<text>[^;,\r\n\"]*)";
    
    
    // 取得符合 Regex 條件的第一筆資料
             Regex reg = new Regex(title);
             Match match = reg.Match(HtmlContext);
             return match.Value;
             
             // 取得符合 Regex 條件的資料集合 
             Regex reg = new Regex(image);
             MatchCollection matchs = reg.Matches(HtmlContext);
             
   

取得資料回傳部份,使用 .NET 3.5 後新增的 JavaScriptSerializer 序列化以 JSON 格式資料輸出。

    // UrlCapture.aspx.cs
    protected void Page_Load(object sender, EventArgs e)
    {
     // 清除 html 格式
     Context.Response.Clear();
        Context.Response.ClearContent();
        Context.Response.ClearHeaders();
        
        // HTML MIME 類型  "text/plain"
        Context.Response.ContentType = "text/plain";
        // HTML 編硯
        Context.Response.ContentEncoding = Encoding.UTF8;
        
        // JavaScriptSerializer : .NET 於 3.5 版本後新增類別,將 Object 序列化。(為 JSON 格式等)
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        
        try{
         string url = "";
         // 取得 QueryString ( GET ) 傳輸資料
         if (Context.Request.QueryString["url"] != null) url = Context.Request.QueryString["url"].ToString();
         // 取得  Form ( POST ) 傳輸資料
         if (Context.Request.Form["ulr"] != null) url = Context.Request.Form["ulr"].ToString();
         
         // 如果  url 為 空值,傳回錯誤訊息 (InputExecption 為自定錯誤型別)
         if (url == "") throw new InputExecption("InputException","URL is null.");
         
         // HtmlCaptureManage : 取得  HTML 資料 
         HtmlCaptureManage capture = new HtmlCaptureManage();
         capture.CaptureHtml(url);
         
         // CaptureData 為  struct
         CaptureData data = new CaptureData();
            data.title = capture.Title();     // 取得 title
            data.description = capture.Description(); // 取得網頁簡介
            data.url = capture.Url();     // 取得 URL
            data.video = capture.Video();    // 取得 Video
            data.picture = capture.Picture();   // 取得 圖片
            data.icon = capture.Icon();     // 取得 Icon
            data.type = "link";
            
            Context.Response.Write(serializer.Serialize(data)); // 將 CaptureData 序列化 為 JSON 並 輸出
            Context.Response.End(); // 結束
        }
        catch (InputExecption ex)
        {
            ExceptionInfo data = new ExceptionInfo();
            data.type = ex.Type;
            data.message = ex.Message;
    
            Context.Response.Write(serializer.Serialize(data)); // 將 錯誤 序列化 為 JSON 並 輸出
            Context.Response.End(); // 結束
        }
    }
     
   

範例下載