以下文字內容,轉載於「旗標知識網

 

相信有些人有這種類似的經驗, 會在桌上放一個自己開發的即時抓取股市數據的小應用程式, 這些數據都來自於一些網站, 像是奇摩股市或是元大證券等網站, 在這些網站上都會提供當日的即時交易數字, 例如每股金額, 漲跌及當日成交量等數字, 這些數字在股市一族的眼中都是可供分析的數字, 在抓取網站的內容後, 再用像Regular Expression (規則運算式) 來抓取需要的數值存起來, 要查詢時再直接由本地過濾過的資料直接抓取即可。

要抓取網站的內容, 需要經由Winsock, 利用HTTP指令來和Web Server溝通, 上傳HTTP POST和HTTP GET, 然後取得伺服器的資料, 上傳的動作稱為Request, 而下載的動作稱為Response。.NET Framework中有直接支援Winsock網路函式庫的System.Net.Sockets命名空間, 有三個主要的類別可用來實作TCP/IP網路通訊的功能:

類別 功能
Socket Winsock 的基底類別, 可用來實作IPv4, IPv6的通訊協定。
TcpClient 以 Winsock 實作的TCP用戶端。
UdpClient 以 Winsock 實作的UDP用戶端。
TcpListener 以 Winsock 實作的TCP伺服端。

 

不過在.NET Framework還提供了一組透過HTTP來存取網站的簡單類別-HttpWebRequest與HttpWebResponse, 專門處理使用HTTP通訊協定連接到遠端Web Server, 以抓取資料的類別, 它還有個很類似的類別, 用來存取FTP的, 稱為FtpWebRequest與FtpWebResponse。

解決方案

若想要抓取網頁內容 (例如用奇摩) 時, 可以利用下列程式碼來實作:

 

以下程式碼為vb.net

 

程式碼 1:用HttpWebRequest開啟簡單的網頁

Imports System.Web
Imports System.Net.Sockets 'HttpWebRequest、HttpWebResponse類別
Imports System.Net
Imports System.IO 'StreamReader類別

在page_load事件裡加入以下

 

Dim request As HttpWebRequest = WebRequest.Create("http://tw.yahoo.com")
        Dim mResponse As HttpWebResponse = request.GetResponse()
        Dim sr As New StreamReader(mResponse.GetResponseStream, Encoding.GetEncoding("utf-8"))

        ' 可設定用什麼編碼來擷取


        Dim strContent = sr.ReadToEnd()
        sr.Close()
        request = Nothing
        mResponse = Nothing
        Response.Write(strContent)

-------------------------------------------------------

若遠端網頁是需要登入時, 則需要加上NetworkCredential, 然後填入帳戶密碼再行連線, 真正的連線行為是發生在HttpWebRequest.GetResponse()時, 所以在這個指令下達前, 所有連線所需要的資訊都要設定好。

若想要知道連線成功或失敗, 可以透過HttpWebResponse.StatusCode來取得, 這個屬性會傳回HTTP的狀態碼, 常用的幾個狀態碼有:

狀態碼 說明
200 OK
403 拒絕存取
404 找不到網頁
405 設定的HTTP動作是不可用的
500 伺服器內部錯誤
503 服務無法使用

 

若想要使用HTTP POST來傳輸資料, 則需要先將傳輸方法設定為POST, 然後將要傳輸的資料寫入到Stream中 (由HttpWebRequest.GetRequestStream() 取得) , 然後再下GetResponse()指令, 例如下列的程式碼:

HttpWebRequest request = WebRequest.Create(strURL) as HttpWebRequest;

request.Method = "POST"; // 設定 HTTP POST
request.ContentLength = strPostData; // 必要項, 設定上傳資料的長度
// 設定為表單類型。
request.ContentType = "application/x-www-form-urlencoded";

StreamWriter sw = new StreamWriter(request.GetRequestStream());

sw.Write(strPostData); // 寫入要上傳的資料到Request Stream中。
sw.Flush();

HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader sr = new StreamReader(response.GetResponseStream(),
System.Text.Encoding.Default);

strResponse = sr.ReadToEnd();

sr.Close();
sw.Close();
request = null;
response = null;

 

下載後的資料解析, 就需要花較多的腦筋了, 可以試著使用MSXML (XmlDocument, 因為HTML其實也是一種XML, 不過若抓取的網站如果不符合XHTML規格, 或者本身的HTML的用法很亂時, 可能會讓XmlDocument擲出例外) 或是Regular Expression來做分析, 或是以已知的路徑方式來搜尋資料。

 

小常識

不要隨便抓取未經授權的網站內容, 小心挨告

HttpWebRequest與HttpWebResponse固然好用, 不過由於用這種方法抓取的內容通常都是未經過合法授權的, 有可能會違反著作權法第91條的重製罪:

擅自以重製之方法侵害他人之著作財產權者, 處三年以下有期徒刑、拘役, 或科或併科新臺幣七十五萬元以下罰金。意圖銷售或出租而擅自以重製之方法侵害他人之著作財產權者, 處六月以上五年以下有期徒刑, 得併科新臺幣二十萬元以上二百萬元以下罰金。以重製於光碟之方法犯前項之罪者, 處六月以上五年以下有期徒刑, 得併科新臺幣五十萬元以上五百萬元以下罰金。著作僅供個人參考或合理使用者, 不構成著作權侵害。

因此, 在抓取別的網站的資料時, 最好是能夠有原作者的書面授權, 以保障自身權益。

arrow
arrow
    全站熱搜

    kingjoy1235 發表在 痞客邦 留言(0) 人氣()