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

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

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

Python网页爬虫实战:从HTML解析到生产级数据清洗 网页爬虫本质是将非结构化HTML文本转化为结构化表格数据的技术过程。其核心原理在于利用HTTP协议获取原始字节流,通过HTML解析器(如lxml)构建DOM树,再基于标签语义(如class='header'、<th>)精准提取字段。技术价值不仅在于自动化采集,更在于建立可验证性、可追溯性与可复现性的数据质量保障机制——例如保存原始HTML快照、校验HTTP状态码、标准化列名、处理HTML实体与空值。典型应用场景包括赛事成绩分析、公开榜单监控、竞品价格追踪等轻量级结构化数据需求。本文以2017 Hillsbo 阅读详情

相关推荐

黑马旅游网编写练习(1)--注册功能

黑马旅游网编写练习 黑马旅游网是包含学习完java-web的一个综合项目;项目中既包含前端,也包含后端的逻辑处理。项目使用三级结构,并未使用框架技术。 本次项目使用maven管理。练习使用一些编写好的前端资源文件;将其放置在本次项目中的src/main/webapp文件下;且还有一些工具类文件,放置在src/main/java/cn/itcast/travel/util文件夹下;在数据库中的实体类...

暮光乐鱼的博客 1762

手把手实现:JS原生代码与Servlet的前后交互实现

1.涉及到的知识 前端语言:javascript,html,如果可以的话,再来一个CSS用于设计样式 后端语言:Java 前端技术:ajax(可以用JQ框架,简单又高效。但是希望用原生代码来写,容易搞懂原理) 后端技术:servlet 2.前端 2.1 首先写一个HTML页面 建议写一个简单页面就可以了。 &lt;!DOCTYPE html&gt; &lt;html&gt; &l...

csdn_xuebing的博客 5446

搭建一个http-server本地服务 搭建本地html页面的服务 启动本地html文件服务

如果在一个html文件中调试h5微信登录之类的问题的话,此时需要将html以服务的名义启动起来,此时就需要用到http-server。2、进入需要启动的项目根目录(index.html所在的文件夹),按住shift,右击鼠标选择在此处打开Powershell。如果需要修改默认端口,比如修改默认的。1、安装http-server。 http-server server html server

u013361179的博客 4654

Windows Mobile使用.NET Compact Framework开发Winform时如何Dispose资源

背景 在开发3G应用的时候,程序退出了,需要自动关闭已经打开的链接。这样需要在Winform退出的时候把其分配的资源都dispose掉。本文讲述Winform Dispose资源的几种方法。 方案 方案一 使用VS2005以上做Winform开发,Visual Studio会自动生成一个用于保存layout信息和处理事件的partial class(...

weixin_34080571的博客 275

创建显示进度的 Windows 窗体控件

创建显示进度的 Windows 窗体控件下面的代码示例演示一个名为 FlashTrackBar 的自定义控件,该控件可用于向用户显示应用程序的级别或进度。它使用渐变以直观的方式表示进度。FlashTrackBar 控件阐释了以下概念: 定义自定义属性。定义自定义事件。((FlashTrackBar 定义 ValueChanged 事件。)重写 OnPaint 方法以提供绘制控件

lcyhjx的专栏 900

JMETER 测试webservice 接口

JMETER JMETER简介 1.Apache JMeter是什么 Apache JMeter 是Apache组织的开放源代码项目,是一个100%纯Java桌面应用,用于压力测试和性能测量。它最初被设计用于Web应用测试但后来扩展到其它测试领域。Apache JMeter可以用于对静态的和动态的资源(文件,Servlet,Perl脚本,Java对象,数据库和查询,FTP服务器或是其它资源)...

chenhu0825的专栏 337

Jquery 秀、无极限------正则表达式Html、CSS、JavaScript基础回顾

---------------------- 路漫漫其修远兮,吾将上下而求索。学无止境!---------------------- 正则表达式: 是一种专门用于操作字符串的规则。 通过一些符号来表示,简化对字符串的复杂操作。 弊端:阅读性差 常见操作: 1.匹配。String matches(regex) 2.查找。Pattern,Matcher     --------

HelloXiaobi 1842

HTML5 相比于 HTML 有哪些更新?

HTML5是HTML标准的重大革新,引入多项关键特性提升Web开发能力。主要更新包括:1)语义化标签(如header、nav)增强代码可读性和SEO;2)原生多媒体支持(video、audio标签)摆脱插件依赖;3)表单功能强化(新增输入类型和验证属性);4)本地存储方案(localStorage、IndexedDB)和离线应用支持;5)丰富API(地理定位、WebSocket等);6)简化语法(DOCTYPE缩减)。这些改进使HTML5成为构建现代Web应用的基础,推动PWA发展,大幅提升跨平台能力。

weixin_45422672的博客 360

Web Service进阶(四)WebService注解_webservice 的 namespace 和 service(1)

*JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串。**CSS:**CSS代码语法,CSS 放置位置,CSS的继承,选择器的种类/优先级,背景样式,字体样式,文本属性,基本样式,样式重置,盒模型样式,浮动float,定位position,浏览器默认样式。1、name :参数的名称。

2301_82243603的博客 580

HTML5核心技术与现代Web开发实践指南

HTML作为Web开发的基石语言,通过标签系统定义文档结构和语义关系。其核心原理是将内容与表现分离,配合CSS和JavaScript实现完整的网页功能。现代HTML5标准新增了语义化标签、多媒体支持等特性,显著提升了SEO效果和无障碍访问能力。在工程实践中,合理使用<article>、<section>等语义元素能获得搜索引擎权重加成,而viewport设置和响应式图片技术则是移动适配的关键。从电商网站到后台管理系统,掌握HTML5的语义化编码和性能优化技巧,已成为前端开发者构建高性能Web应用的必备技能。

weixin_33671935的博客 449

AI智能体Web自动化实战:基于browser-use框架的智能网页操作指南

Web自动化是提升工作效率、实现流程自动化的关键技术,其核心在于模拟用户操作与网页交互。传统方案如Selenium依赖预设脚本,虽稳定但缺乏灵活性,难以应对动态变化的网页结构。随着大语言模型(LLM)的发展,AI驱动的自动化通过自然语言理解与决策能力,为这一领域带来了范式变革。其技术价值在于将人类的意图转化为可执行的浏览器操作,实现了从“如何做”到“做什么”的抽象跃升。在实际应用中,这种智能自动化特别适用于数据抓取、表单填写、状态监控等需要语义理解的场景。本文聚焦的browser-use框架,正是这一理念的

weixin_33895695的博客 366

Flutter web_scraper在鸿蒙生态的跨平台数据采集实践

网页抓取技术作为数据采集的重要手段,通过解析HTML结构和提取关键信息,为业务决策提供数据支撑。其核心原理基于HTTP请求和DOM解析,开发者常用的CSS选择器或XPath定位元素。在移动端场景下,Flutter的web_scraper库展现出独特优势,特别是与鸿蒙(HarmonyOS)分布式能力结合时,能构建多设备协同的采集网络。这种技术组合解决了传统爬虫难以在移动端实现闭环体验的痛点,适用于电商监控、舆情分析等场景。通过合理使用正则表达式清洗数据和分布式任务调度,可显著提升采集效率。在鸿蒙生态中,还需特

weixin_30838873的博客 599

HTML5从入门到精通:网页开发基础与语义化标签详解

超文本标记语言(HTML)是构建万维网内容的基础技术,它通过标签系统定义网页的结构与语义。其核心原理在于使用预定义的标签元素来描述内容类型,如标题、段落、图像和链接,从而为浏览器提供渲染页面的蓝图。这项技术的价值在于实现了内容与表现的分离,为搜索引擎优化和无障碍访问提供了结构化基础。在应用场景上,HTML是前端开发三驾马车(HTML、CSS、JavaScript)的基石,广泛应用于网站构建、博客平台、Web应用界面等所有网页内容展示领域。随着HTML5标准的普及,语义化标签如header、nav、artic

weixin_30797199的博客 302

高级网页数据提取实战指南:Firecrawl专业解决方案深度解析

还在为动态网页数据提取的复杂性而困扰吗?Firecrawl作为一款革命性的网页数据提取工具,能够将任何网站转换为AI友好的结构化数据,彻底改变传统爬虫的工作方式。本文将为技术决策者和开发者提供完整的Firecrawl实战指南,涵盖从核心概念到高级部署的全方位解决方案。 ## 🔍 网页数据提取的挑战与创新解决方案 **传统爬虫技术的三大痛点:** 1. **动态内容处理困难** - 现代网站大

gitblog_00842的博客 634

Java Web应用XSS漏洞审计:从原理到实战的代码级防御

跨站脚本攻击(XSS)是Web安全领域的核心威胁之一,其本质源于应用对用户输入数据的过度信任与不当处理。攻击者通过注入恶意脚本,可在受害者浏览器中执行任意代码,从而窃取敏感信息、劫持用户会话或发起钓鱼攻击。从技术原理看,XSS主要分为反射型、存储型和DOM型三类,其危害性依次递增,尤其存储型XSS因持久化特性常被用于大规模数据窃取。在Java Web开发中,漏洞常出现在JSP/Thymeleaf模板直接输出、不安全的API拼接、富文本处理不当等场景。例如,在**代码审计**过程中,若发现用户输入未经转义便通

weixin_33675507的博客 502

VideoDownloadHelper技术实现深度指南:网页视频解析与下载架构解析

VideoDownloadHelper是一个开源Chrome扩展项目,专注于解决网页视频资源解析与下载的技术难题。该项目采用模块化架构设计,通过智能解析引擎实现对多种视频格式和动态加载内容的精准捕获,为开发者提供了一个可扩展的视频解析解决方案。 ## 解析引擎工作原理与技术架构 VideoDownloadHelper的核心技术架构基于Chrome Extension Manifest V3规范

gitblog_00436的博客 426

Java web 学习

由于本人是个新手,对java web了解不多,所以在这里把看见过的精彩的知识点记录下来,希望帮到各位. 阶段的总结,是进步的一大助力,现在总结下课程设计。 第一个网站:基于PHP的购书网站 现在感到网站的本质是:数据的流动。 网站一开始,完全不懂后台,所以就只做了前台先。 做前端,就是html,CSS,javascript,jQuery。 在这个过程中,接触到了很多库,框架,js插...

天才中年英俊的博客 168
上一篇: Regular Expression 正则表达式-4 (C++)
下一篇: 让我们用中文编程
DanceFire
博客等级 码龄25年 91粉丝 42原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值