分享
 
 
 

利用正则表达式将html网页数据变成Web Service

王朝html/css/js·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这次的题目很简单,中国银行有一个查当天汇率的网页(http://www.bank-of-china.com/info/qpindex.shtml),不过是传统的Html格式,而其又没有提供Xml格式或者WebService查询。现在如果希望其他的信息系统能够随时读取其中的数据,那么方便的莫过于中行提供一个WebService接口供大家调用,这也是典型的安全的WebService应用。可惜中行没有做,那么我们能不能自己来做呢?当然可以,只要用程序分析其html网页,那么就可以很容易的读取其中的数据。文本分析,当然要看我们的"Regular Expression"(呵呵,其实这才是写这个程序的真实目的 -- 应用正则表达式。)

中行的页面类似于:

日期:2004/09/30 有效期至2004/10/07

货币名称

现汇买入价

现钞买入价

卖出价

基准价

英镑

1488.1700

1453.1500

1492.6400

港币

105.9700

105.3300

106.2900

106.1100

美元

826.4200

821.4500

828.9000

827.6600

瑞士法郎

655.9300

641.1400

659.2200

新加坡元

488.7600

477.2600

490.2300

瑞典克朗

112.4900

109.8400

112.8300

丹麦克朗

136.5900

133.3700

137.0000

挪威克朗

121.9500

119.0800

122.3100

日元

7.4344

7.3785

7.4717

7.4519

加拿大元

650.8000

635.4800

652.7600

澳大利亚元

591.9900

578.6400

594.9600

欧元

1019.6400

1010.9600

1022.7000

1019.7000

澳门元

103.2200

102.6000

103.5300

菲律宾比索

14.6700

14.3300

14.7200

泰国铢

19.9000

19.4300

19.9600

新西兰元

553.7000

555.3600

对其代码分析后,给出了一个正则表达式,当然这个表达式还不完善,但是针对目前比较固定的中行的汇率页面来说,暂时还没有问题。

@"<tr bgcolor='#\w+' ><td height='20'>(?<currency>.*)</td>\s*" +

@"<td height='20'><p align='right'>(?<bankbuytt>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<buynotes>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<sell>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<base>\d*.?\d*)(&nbsp)+.?</td>\s*"

然后过滤就非常简单了。我一直以为代码是最好的说明,特别是对于优雅的语言来说,因为我就不多说了,代码伺候。

这是所建WebService页面ForeignExchange.asmx的代码:

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.Web;

using System.Net;

using System.Web.Services;

using System.Xml;

using System.Text;

using System.Text.RegularExpressions;

using System.IO;

namespace ChinaBank

{

/// <summary>

/// Summary description for ForeignExchange.

/// </summary>

[WebService(Namespace="http://dancefires.com/ChinaBank/")]

public class ForeignExchange : System.Web.Services.WebService

{

public ForeignExchange()

{

//CODEGEN: This call is required by the ASP.NET Web Services Designer

InitializeComponent();

}

#region Component Designer generated code

//Required by the Web Services Designer

private IContainer components = null;

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if(disposing && components != null)

{

components.Dispose();

}

base.Dispose(disposing);

}

#endregion

[WebMethod]

public XmlDataDocument GetForeignExchangeRates()

{

return getXmlDoc();

}

[WebMethod]

public DataSet GetForeignExchangeRatesDataSet()

{

return getXmlDoc().DataSet;

}

[WebMethod]

public string GetBankPage()

{

return getWebContent( "http://www.bank-of-china.com/info/whjrpj.html" );

}

// private methods

private string getWebContent( string url )

{

using( WebClient client = new WebClient() )

{

byte[] buffer = client.DownloadData( url );

string str = Encoding.GetEncoding("GB2312").GetString( buffer, 0, buffer.Length );

return str;

}

}

private XmlDataDocument getXmlDoc()

{

string webcontent = getWebContent("http://www.bank-of-china.com/info/whjrpj.html");

// Prepair for DataSet

DataSet ds = new DataSet("Exchange");

DataTable dt = new DataTable("ForeignExchange");

ds.Tables.Add( dt );

dt.Columns.Add( "Currency", typeof(string) );

dt.Columns.Add( "BankBuyTT", typeof(double) );

dt.Columns.Add( "BankBuyNotes", typeof(double) );

dt.Columns.Add( "BankSell", typeof(double) );

dt.Columns.Add( "Baseline", typeof(double) );

XmlDataDocument xmldoc = new XmlDataDocument( ds );

Regex expr = new Regex(

@"<tr bgcolor='#\w+' ><td height='20'>(?<currency>.*)</td>\s*" +

@"<td height='20'><p align='right'>(?<bankbuytt>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<buynotes>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<sell>\d*.?\d*)(&nbsp)+.?</td>\s*" +

@"<td height='20'><p align='right'>(?<base>\d*.?\d*)(&nbsp)+.?</td>\s*"

, RegexOptions.Compiled);

for( Match m = expr.Match(webcontent) ; m.Success ; m=m.NextMatch() )

{

string key;

DataRow row = dt.NewRow();

row["Currency"] = m.Groups["currency"];

key = m.Groups["bankbuytt"].ToString();

row["BankBuyTT"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;

key = m.Groups["buynotes"].ToString();

row["BankBuyNotes"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;

key = m.Groups["sell"].ToString();

row["BankSell"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;

key = m.Groups["base"].ToString();

row["Baseline"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;

dt.Rows.Add( row );

}

return xmldoc;

}

}

}

客户端也很容易,只要用wsdl生成了相应的WebService Proxy后,直接调用就行了,由于我让Server端返回了DataSet,因此客户端直接用DataGrid来显示DataSet即可,非常Easy,在这个问题上客户端没有什么技术关键点。

using System;

using System.Threading;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

namespace BankDataClient

{

/// <summary>

/// Summary description for frmMainBankRates.

/// </summary>

public class frmMainBankRates : System.Windows.Forms.Form

{

private System.Windows.Forms.DataGrid dataGrid1;

private System.Windows.Forms.Button btnConnect;

private System.Data.DataSet ds;

private BankDataClient.com.dancefires.www.ForeignExchange proxy = new BankDataClient.com.dancefires.www.ForeignExchange();

private System.Windows.Forms.TextBox txtUrl;

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

public frmMainBankRates()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

try

{

txtUrl.Text = System.Configuration.ConfigurationSettings.AppSettings["url"];

proxy.Url = txtUrl.Text;

}

catch(Exception)

{

proxy.Url = "http://www.dancefires.com/ChinaBank/ForeignExchange.asmx";

txtUrl.Text = proxy.Url;

}

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if(components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.dataGrid1 = new System.Windows.Forms.DataGrid();

this.ds = new System.Data.DataSet();

this.btnConnect = new System.Windows.Forms.Button();

this.txtUrl = new System.Windows.Forms.TextBox();

((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();

((System.ComponentModel.ISupportInitialize)(this.ds)).BeginInit();

this.SuspendLayout();

//

// dataGrid1

//

this.dataGrid1.DataMember = "";

this.dataGrid1.DataSource = this.ds;

this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;

this.dataGrid1.Location = new System.Drawing.Point(32, 48);

this.dataGrid1.Name = "dataGrid1";

this.dataGrid1.Size = new System.Drawing.Size(480, 256);

this.dataGrid1.TabIndex = 0;

//

// ds

//

this.ds.DataSetName = "Exchange";

this.ds.Locale = new System.Globalization.CultureInfo("zh-CN");

//

// btnConnect

//

this.btnConnect.Location = new System.Drawing.Point(432, 16);

this.btnConnect.Name = "btnConnect";

this.btnConnect.TabIndex = 1;

this.btnConnect.Text = "连接";

this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);

//

// txtUrl

//

this.txtUrl.Location = new System.Drawing.Point(32, 16);

this.txtUrl.Name = "txtUrl";

this.txtUrl.Size = new System.Drawing.Size(384, 20);

this.txtUrl.TabIndex = 2;

this.txtUrl.Text = "";

//

// frmMainBankRates

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(544, 318);

this.Controls.Add(this.txtUrl);

this.Controls.Add(this.btnConnect);

this.Controls.Add(this.dataGrid1);

this.Name = "frmMainBankRates";

this.Text = "Foreign Exchange Rates of Bank of China";

((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();

((System.ComponentModel.ISupportInitialize)(this.ds)).EndInit();

this.ResumeLayout(false);

}

#endregion

private void btnConnect_Click(object sender, System.EventArgs e)

{

UpdateDataGrid();

}

private void UpdateDataGrid()

{

try

{

btnConnect.Enabled = false;

txtUrl.ReadOnly = true;

proxy.Url = txtUrl.Text;

ds = proxy.GetForeignExchangeRatesDataSet();

dataGrid1.SetDataBinding( ds, "ForeignExchange" );

dataGrid1.Update();

}

catch( Exception err )

{

MessageBox.Show( err.Message );

}

finally

{

txtUrl.ReadOnly = false;

btnConnect.Enabled = true;

}

}

[STAThread]

static void Main( string[] args )

{

Application.Run( new frmMainBankRates() );

}

}

}

有了这个例子,应该可以从中了解最基本的XML, WebService, Regular Expression, DataSet, DataGrid的知识。

软件所有代码,及相关截屏可以从下面的连接中获得:

http://www.dancefires.com/ChinaBank/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有