C# 抓取網頁內容的方法

一、抓取通常內容html

須要三個類:WebRequest、WebResponse、StreamReader瀏覽器

所需命名空間:System.Net、System.IO服務器

核心代碼:網絡

view plaincopy to clipboardprint?app

代碼以下:

WebRequest request = WebRequest.Create("http://www.jb51.net/");  
WebResponse response = request.GetResponse();  
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312")); 
 
WebRequest 類的 Create 爲靜態方法,參數爲要抓取的網頁的網址;

      Encoding 指定編碼,Encoding 中有屬性 ASCII、UTF3二、UTF8 等全球通用的編碼,但沒有 gb2312 這個編碼屬性,因此咱們使用 GetEncoding 得到 gb2312 編碼。編碼

示例:url

view plaincopy to clipboardprint?spa

代碼以下:

<%@ Page Language="C#" %>  
<%@ Import Namespace="System.Net" %>  
<%@ Import Namespace="System.IO" %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<mce:script runat="server"><!--  
    void Page_Load(object sender, EventArgs e)  
    {  
        try  
        {  
            WebRequest request = WebRequest.Create("http://www.jb51.net/");  
            WebResponse response = request.GetResponse();  
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312"));  

            tb.Text = reader.ReadToEnd();  

            reader.Close();  
            reader.Dispose();  
            response.Close();  
        }  
        catch (Exception ex)  
        {  
            tb.Text = ex.Message;  
        }  
    }  
// --></mce:script>   
<html xmlns="http://www.w3.org/1999/xhtml" >  
<head runat="server">  
    <title>抓取網頁內容 - 千一網絡</title>  
</head>  
<body>  
    <form id="form1" runat="server">  
    <div>  
    <asp:TextBox ID="tb" runat="server" Width="500" Height="300" TextMode="multiLine"></asp:TextBox>  
    </div>  
    </form>  
</body>  
</html>  

2 抓取網頁內容-圖片

    須要四個類:WebRequest、WebResponse、Stream、FileStream。.net

   示例:設計

view plaincopy to clipboardprint?

代碼以下:

<%@ Page Language="C#" %>  
<%@ Import Namespace="System.Net" %>  
<%@ Import Namespace="System.IO" %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<mce:script runat="server"><!--  
    void Page_Load(object sender, EventArgs e)  
    {  
        try  
        {  
            WebRequest request = WebRequest.Create("http://www.jb51.net/images/logo.gif");  
            WebResponse response = request.GetResponse();  
            Stream reader = response.GetResponseStream();  

            FileStream writer = new FileStream("D://logo.gif", FileMode.OpenOrCreate, FileAccess.Write);  
            byte[] buff = new byte[512];  
            int c = 0; //實際讀取的字節數   
            while ((c=reader.Read(buff, 0, buff.Length)) > 0)  
            {  
                writer.Write(buff, 0, c);  
            }  
            writer.Close();  
            writer.Dispose();  

            reader.Close();  
            reader.Dispose();  
            response.Close();  

            tb.Text = "保存成功!";  
        }  
        catch (Exception ex)  
        {  
            tb.Text = ex.Message;  
        }  
    }  
// --></mce:script>   
<html xmlns="http://www.w3.org/1999/xhtml" >  
<head runat="server">  
    <title>抓取網頁圖片並保存 - 千一網絡</title>  
</head>  
<body>  
    <form id="form1" runat="server">  
    <div>  
    <asp:TextBox ID="tb" runat="server" Width="500" Height="300" TextMode="multiLine"></asp:TextBox>  
    </div>  
    </form>  
</body>  
</html>  

 

3 抓取網頁內容-Post 數據

   在抓取網頁時,有時候,須要將某些數據經過 Post 的方式發送到服務器,將如下代碼添加在網頁抓取的程序中,以實現將用戶名和密碼 Post 到服務器

view plaincopy to clipboardprint?

代碼以下:

string data = "userName=admin&passwd=admin888";  
byte[] requestBuffer = System.Text.Encoding.GetEncoding("gb2312").GetBytes(data);  

request.Method = "POST";  
request.ContentType = "application/x-www-form-urlencoded";  
request.ContentLength = requestBuffer.Length;  
using (Stream requestStream = request.GetRequestStream())  
{  
    requestStream.Write(requestBuffer, 0, requestBuffer.Length);  
    requestStream.Close();  
}  

using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312")))  
{  
    string str = reader.ReadToEnd();  
    reader.Close();  
}  

 


4  抓取網頁內容-防止重定向

在抓取網頁時,成功登陸服務器應用系統後,應用系統可能會經過 Response.Redirect 將網頁進行重定向,若是不須要響應這個重定向,那麼,咱們就不要把 reader.ReadToEnd() 給 Response.Write 出來,就能夠了。

 

5 抓取網頁內容-保持登陸狀態

利用 Post 數據成功登陸服務器應用系統後,就能夠抓取須要登陸的頁面了,那麼咱們就可能須要在多個 Request 間保持登陸狀態。

首先,咱們要使用 HttpWebRequest,而不是 WebRequest。

與 WebRequest 相比,變化的代碼是:

view plaincopy to clipboardprint?

代碼以下:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);  

 

注意:HttpWebRequest.Create 返回的類型還是 WebRequest,因此要轉化一下。

其次,使用 CookieContainer。

view plaincopy to clipboardprint?

代碼以下:

System.Net.CookieContainer cc = new System.Net.CookieContainer();  
request.CookieContainer = cc;  
request2.CookieContainer = cc;   
 
這樣 request 和 request2 之間就使用了相同的 Session,若是 request 登陸了,那麼 request2 也是登陸狀態。

最後,如何在不一樣的頁面間使用同一個 CookieContainer。

要在不一樣的頁面間使用同一個 CookieContainer,只有把 CookieContainer 加入 Session。

代碼以下:

view plaincopy to clipboardprint?
Session.Add("ccc", cc); //存   

CookieContainer cc = (CookieContainer)Session["ccc"]; //取  

 

5 抓取網頁內容-把當前會話帶到 WebRequest 中

好比說瀏覽器 B1 去訪問服務器端 S1,這會產生一個會話,而服務器端 S2 再用 WebRequest 去訪問服務器端 S1,這又會產生一個會話。如今的需求是讓 WebRequest 使用瀏覽器 B1 與 S1 之間的會話,也就是說要讓 S1 認爲是 B1 在訪問 S1,而不是 S2 在訪問 S1。

這就要利用 Cookie 了,先在 S1 中取得與 B1 的 SessionID 的 Cookie,再將這個 Cookie 告訴 S2,S2 再將 Cookie 寫在 WebRequest 中。

view plaincopy to clipboardprint?

代碼以下:

WebRequest request = WebRequest.Create("url");  
<SPAN class="key">request.Headers.Add(HttpRequestHeader.Cookie, "ASPSESSIONIDSCATBTAD=KNNDKCNBONBOOBIHHHHAOKDM;");</SPAN>  
WebResponse response = request.GetResponse();  
StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312"));  
Response.Write(reader.ReadToEnd());  
reader.Close();  
reader.Dispose();  
response.Close();  

 

要說明的是:

本文並非 Cookie 欺騙,由於 SessionID 是 S1 告訴 S2 的,並非 S2 竊取的,雖然有些古怪,但這可能在一些特定的應用系統中會有用。
S1 必需要向 B1 寫 Session,這樣 SessionID 纔會保存到 Cookie 中,而且 SessionID 纔會保持不變。
在 ASP.NET 中取 Cookie 用 Request.Cookies,本文假設 Cookie 已經取出來。
不一樣的服務器端語言,SessionID 在 Cookie 中上名稱並不同,本文是 ASP 的 SessionID。
S1 可能不單單依靠 SessionID 來判斷當前登陸,它可能還會輔助於 Referer、User-Agent 等,這取決於 S1 端程序的設計。
其實本文算是本連載中「保持登陸狀態」的另外一種方法。


6 抓取網頁內容-如何更改來源 Referer 和 UserAgent

view plaincopy to clipboardprint?

代碼以下:

SPAN class="caution">HttpWebRequest</SPAN> request = <SPAN class=caution>(HttpWebRequest)HttpWebRequest</SPAN>.Create("http://127.0.0.1/index.htm");  
//request.Headers.Add(HttpRequestHeader.Referer, "http://www.jb51.net/"); // 錯誤   
//request.Headers[HttpRequestHeader.Referer] = "http://www.jb51.net/"; // 錯誤   
<SPAN class="caution">request.Referer</SPAN> = "http://www.jb51.net/"; // 正確  
 
註釋掉的兩句是不對的,會發生錯誤:

view plaincopy to clipboardprint?
此標頭必須使用適當的屬性進行修改。  
參數名: name  
此標頭必須使用適當的屬性進行修改。參數名: name

UserAgent 相似。

相關文章
相關標籤/搜索