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

转载 2004年10月05日 16:02:00

这次的题目很简单,中国银行有一个查当天汇率的网页(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.[url]www.ForeignExchange[/url] 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/

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

这次的题目很简单,中国银行有一个查当天汇率的网页(http://www.bank-of-china.com/info/qpindex.shtml),不过是传统的Html格式,而其又没有提供Xml格式或...
  • DanceFire
  • DanceFire
  • 2004年10月04日 21:06
  • 2941

使用正则表达式,从网站上获取指定数据

最近做的一个项目中,其中有这样一个需求:用户要求我们实时在地图上显示某些指定景点的人数,但是却没有给我们数据的接口。不过可以从网页上获取到最新的数据,每小时更新一次。所以经理安排我做一个实时从网页上抓...
  • xiaoxian8023
  • xiaoxian8023
  • 2014年07月31日 00:16
  • 5206

如何将pdf转换成html网页格式

我们在日常生活与工作当中有时会碰到PDF与HTML这两种不同的文件格式,PDF最为职场里使用频率最高的高质量格式转换器,是每个企业和公司之间交汇的重要媒介,而HTML页面则是也是目前通用的传播格式,它...
  • pdfhtml
  • pdfhtml
  • 2015年09月11日 14:11
  • 780

常用正则表达式爬取网页信息及分析HTML标签总结

见链接 https://yq.aliyun.com/articles/26026摘要: 这篇文章主要是介绍Python爬取网页信息时,经常使用的正则表达式及方法。它是一篇总结性文章,实用性比较大,主...
  • chaowanghn
  • chaowanghn
  • 2017年02月05日 09:33
  • 2593

HTML5网页定位,并将位置绘在百度地图上

运行效果: 实现代码: HTML5定位 * { margin: 0px; padding: 0px...
  • a497785609
  • a497785609
  • 2015年11月20日 12:02
  • 5867

利用正则表达式去掉html代码

 using System.Text.RegularExpressions;//需要引用  // 利用正则表达式去掉""之间的内容  private string StripHT(string str...
  • ecitnet
  • ecitnet
  • 2007年10月17日 17:04
  • 644

做了一个网页版的串口调试助手

serial-webDebug项目github 项目地址简介对于web爱好者来说,在web上做一些事情真的很酷。这个项目通过使用serialport包调用底层的串口,完成串口的收发。和桌面软件的串口调...
  • a912293097
  • a912293097
  • 2016年03月21日 00:17
  • 3910

Python爬取网页信息时,经常使用的正则表达式及方法

这篇文章主要是介绍Python爬取网页信息时,经常使用的正则表达式及方法。它是一篇总结性文章,实用性比较大,主要解决自己遇到的爬虫问题,也希望对你有所帮助~ 当然如果会Selenium基于自动化测试...
  • baidu_21833433
  • baidu_21833433
  • 2017年04月19日 16:04
  • 734

关于web页面清洗的一些记录,杂乱、待梳理和深入

页面模板匹配,开源库,web页面清洗     是否可以考虑提供一个样本页面,由用户选中要提取的数据块,程序再把所有类似页面中该数据块所在位置的数据提取出来?     页面清洗器 WPAR,Webw...
  • xiarendeniao
  • xiarendeniao
  • 2012年06月03日 00:31
  • 1926

[python] 常用正则表达式爬取网页信息及分析HTML标签总结

这篇文章主要是介绍Python爬取网页信息时,经常使用的正则表达式及方法。它是一篇总结性文章,实用性比较大,主要解决自己遇到的爬虫问题,也希望对你有所帮助~ 1.获取标签之间内容 2.获取超链接之间内...
  • Eastmount
  • Eastmount
  • 2016年04月07日 06:13
  • 41653
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用正则表达式将html网页数据变成Web Service
举报原因:
原因补充:

(最多只允许输入30个字)