適用平台:
適用範圍:□ ASP.NET 1.0 □ ASP.NET 1.1 □ ASP.NET 2.0 □ ASP.NET 3.5
問題
最近公司有一些需求, 要到其他公司提供的網站中抓取數值, 存到公司的資料庫中再取出來分析使用, 網址已經知道了, 那我要如何在ASP.NET中去抓取指定網址的資料?
問題說明
相信有些人有這種類似的經驗, 會在桌上放一個自己開發的即時抓取股市數據的小應用程式, 這些數據都來自於一些網站, 像是奇摩股市或是元大證券等網站,
在這些網站上都會提供當日的即時交易數字, 例如每股金額, 漲跌及當日成交量等數字, 這些數字在股市一族的眼中都是可供分析的數字, 在抓取網站的內容後,
再用像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。
解決方案
若想要抓取網頁內容 (例如用奇摩查詢台積電的股票) 時, 可以利用下列程式碼來實作:
程式碼 1:用HttpWebRequest開啟簡單的網頁 |
HttpWebRequest request = WebRequest.Create(
"http://tw.stock.yahoo.com/q/q?s=2330") as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader sr = new StreamReader(response.GetResponseStream(),
System.Text.Encoding.Default);
strContent = sr.ReadToEnd();
sr.Close();
request = null;
response = null;
|
若遠端網頁是需要登入時, 則需要加上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條的重製罪:
擅自以重製之方法侵害他人之著作財產權者, 處三年以下有期徒刑、拘役,
或科或併科新臺幣七十五萬元以下罰金。意圖銷售或出租而擅自以重製之方法侵害他人之著作財產權者, 處六月以上五年以下有期徒刑,
得併科新臺幣二十萬元以上二百萬元以下罰金。以重製於光碟之方法犯前項之罪者, 處六月以上五年以下有期徒刑,
得併科新臺幣五十萬元以上五百萬元以下罰金。著作僅供個人參考或合理使用者, 不構成著作權侵害。
因此, 在抓取別的網站的資料時, 最好是能夠有原作者的書面授權, 以保障自身權益。 |
|