這一次碰到的情況是這樣的,要作一個與某站台具有相同的資料,不過這個資料沒有辦法用 XML 給你,也就是說你必需要從別的網站抓點資料過來,然後在自己的網站上頭顯示,或是作一些處理之後再顯示出來。這樣子作顯然是不合法的,雖然很不想作這樣的事,不過有的時候是真的沒有辦法拿到資料。相信很多人跟我有同樣的情況,所以會有現在這個範例出來。

由於我這邊的後續處理會有些比較麻煩的動作,所以要把資料給存在自己的 SQL Server 中,我需要引用資料庫相關的東西。

using System;
using System.Net;
using System.IO;
using System.Data;
using System.Data.SqlClient;

先設定一下資料庫主機及登入的相關資訊:

string sDB_Host = “192.168.1.200”;
string sDB_User = “sa”;
string sDB_Pass = “”;
string sDB_Data = “testdb”;
string strConn = “database=” + sDB_Data + “;server=” + sDB_Host + “;user id=” + sDB_User + “;password=” + sDB_Pass + “;”;
SqlConnection conn1 = new SqlConnection(strConn);
try
{
conn1.Open();
}
catch
{
Console.WriteLine (“SQL connect failed… Please check arguments:”);
Console.WriteLine (“DB_HOST: {0}”, sDB_Host);
Console.WriteLine (“DB_DATA: {0}”, sDB_Data);
Console.WriteLine (“DB_USER: {0}”, sDB_User);
Console.WriteLine (“DB_PASS: {0}”, sDB_Pass);
return;
}

使用 HttpWebRequest 來抓取對方站台上的資料,用 HttpWebResponse 來接收資料,最後的 Stream 經過一些處理指定給 myResponse 這個字串變數。

// Start HTTP Grab
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(“http://www.fakeserver.com/default.asp”);
HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();
Stream myStr = myRes.GetResponseStream();
StreamReader streamRead = new StreamReader( myStr );

string myResponse = “”;
Char[] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256 );
while (count > 0)
{
String outputData = new String(readBuff, 0, count);
myResponse += outputData;
count = streamRead.Read(readBuff, 0, 256);
}

一直到上面為止,我們已經抓到所要的網站資訊到字串變數中了,接下來就是要作字串的分解,由於每個人的需求不一樣,所以請依需要自行修改。首先我先定義了字頭與字尾,然後來把所需要的那一段資料給解出來。

string strFirstST = “<td> <div align=”center”><img src=”/Img/product1.gif” alt=’Chip’></div></td>”;
string strFirstEN = “</table>”;
myResponse = myResponse.Substring (myResponse.IndexOf(strFirstST));
myResponse = myResponse.Substring (0, myResponse.IndexOf(strFirstEN));

然後我寫了一個小函式,用來把我認為不需要的 HTML 碼給 trim 掉,就是去掉所有的 HTML Tag:
static string removeHtmlTag (string source)
{
int debut;
int fin;
string theTag;

debut = source.IndexOf(“<“);
fin = source.IndexOf(“>”);

while ((debut >= 0) && (fin > 0))
{
debut = source.IndexOf(“<“);
fin = source.IndexOf(“>”);
if (debut >= fin) { debut = 0; }
fin = fin – debut;
theTag = source.Substring (debut, fin + 1);
if (theTag != “”) { source = source.Replace (theTag,””); }
}

source = source.Replace(“&nbsp;”, ” “);
source = source.Replace(“&gt;”, “>”);
source = source.Replace(“&amp;”, “&”); // Trim ??
return source;
}
雖然寫得不是很完整,不過已經可以符合我的需求了,如果對你來說還不夠,可以再加一些 replace 的程式進去。然後可以這樣利用這一個函式:

// Trim HTML Tag
myResponse = removeHtmlTag(myResponse);

我準備存進 SQL 中,要知道今天的日期:
// What day is today
string sToday = DateTime.Today.ToString();
sToday = sToday.Substring(0, sToday.IndexOf(” “));
sToday = sToday.Replace(“/”,”-“);

把得到的資料再分解,這邊是我自己的需求,也許每個人得到的資料與各自程式所需要的不同,應該針對資料的部分來進行拆解的動作,這裡只是示範一些不是很聰明的字串拆解,拆解後會依照不同的資料,分別寫入 SQL 資料庫中:

// Split each item
string[] sItem = new string[5];
int i = 0;
char[] splitChar = new char[] {‘\n’,’r’};
foreach (string subString in myResponse.Split(splitChar))
{
if (subString.Length >= 4)
{
sItem[i] = subString;
i++;
if (i == 5)
{
Console.WriteLine (“Item: {0}”, sItem[0]);
Console.WriteLine (“P1: {0}”, sItem[1]);
Console.WriteLine (“P2: {0}”, sItem[2]);
Console.WriteLine (“P3: {0}”, sItem[3]);
Console.WriteLine (“St: {0}”, sItem[4]);
// Write to SQL
string sSQL = “INSERT INTO PriceOil VALUES(‘” + sItem[0] + “‘,” + sItem[1] + “,” + sItem[2] + “,” + sItem[3] + “,'” + sItem[4] + “‘,'” + sToday + “‘)”;
SqlCommand sqlCdCmd1 = new SqlCommand(sSQL, conn1);
SqlDataReader sqlDrReader1;
sqlDrReader1 = sqlCdCmd1.ExecuteReader();
sqlDrReader1.Close();
i = 0;
}
}
}

基本上就是這樣啦,[1] 抓資料 [2] 拆資料 [3] 寫進資料庫,然後,接下來要怎麼顯示,就直接從自己的資料庫中把資料庫抓出來秀出,或是日後可以作分析用。如果你的這支程式需要固定的時間跑一次,就把它給放進 Schedule Task 中吧。

— SAMPLE RESULT FOR STOCK RECORDS

stock-grab.png

[End]

最後修改日期: 2004-01-08