随笔 - 170  文章 - 536  trackbacks - 0
<2007年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

我参与的团队

随笔分类(103)

搜索

  •  

积分与排名

  • 积分 - 412675
  • 排名 - 135

最新评论

阅读排行榜

上一篇中我们说到了,如何使用 HttpClient 抓取所需要的数据,接下来介绍一下如何对这些数据进行处理。基本的处理原理是使用正则表达式进行内容的匹配。

为了便于处理,我们首先把使用 HttpClient 抓取到的数据做一些简单的处理。

第一步要做的就是删除回车符,当然我不会写含有回车符的正则表达式才会这么写的,当然如果您有更好的方法也可以不用这么做。

代码很简单:

1protected String removeEnter(String response) {
2    response = StringUtils.replace(response, "\r\n""");
3    response = StringUtils.replace(response, "\n""");
4    return response;
5}

接下来就可以使用正则表达式来对所抓取的内容进行匹配了:

正则表达式是一种可以用于模式匹配和替换的强有力的工具,一个正则表达式就是由普通的字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式,它描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。正则表达式在字符数据处理中起着非常重要的作用,我们可以用正则表达式完成大部分的数据分析处理工作,如:判断一个串是否是数字、是否是有效的Email地址,从海量的文字资料中提取有价值的数据等等,如果不使用正则表达式,那么实现的程序可能会很长,并且容易出错。对这点本人深有体会,面对大量工具书电子档资料的整理工作,如果不懂得应用正则表达式来处理,那么将是很痛苦的一件事情,反之则将可以轻松地完成,获得事半功倍的效果。

在这里,我使用了 Jakarta-ORO 作为正则表达式工具来进行匹配。

Jakarta-ORO是最全面以及优化得最好的正则表达式API之一,Jakarta-ORO库以前叫做OROMatcher,是由Daniel F. Savarese编写,后来他将其赠与Jakarta Project,读者可在jakarta.apache.org的网站下载该API包。
因为在这里我们不需要用到太多正则表达式的知识,仅仅是简单的用用而已,所以几行简单的代码就可以解决问题:
protected String match(String response, String template, int index) {
    Perl5Util engine 
= new Perl5Util();
    String name 
= null;
    
if (response != null{
        
if (engine.match(template, response)) {
            name 
= engine.group(index);
        }

    }

    
return name;
}

第一个参数 response 表示抓取到的页面源码,第二个参数 template 表示我们预先设定的模板,第三个表示第几个匹配。返回的结果是匹配成功的 group 中的内容。

于是我们可以这样的调用它:

String template = "/(沪综指)</font></b></a> <span id=\"STK1\">(\\d{4,5}\\.\\d{1,4})</span>";
String name 
=  match(response, template, 1);
String index 
=  match(response, template, 2);

注意一下,我们正则表达式前后都有 "/"。
另外,我们用() 括起来的部分表示我们要匹配的内容,所以这里 name 可以匹配到 沪综指,index 可以匹配到大盘的点数。 

该匹配对应于: http://web7.jrj.com/homev1/StockIndex.htm
为了防止页面以后打不开了大家找不到,我把其中相关的匹配部分的页面源码也发出来:

<href=javascript:ShowImg('000001',2) target=_self><b><font color=#000000>沪综指</font></b></a> <span id="STK1">3914.20</span> <span id="STK2" class="c1"><img src=/HomeV1/images/down.gif width=8 height=8>164.40</span> <href=javascript:ShowImg('399001',1) target=_self><b><font color=#000000>深成指</font></b></a> <span id="STK3">12882.17</span> <span id="STK4" class="c1"><img src=/HomeV1/images/down.gif width=8 height=8>701.53</span> <href=javascript:ShowImg('399300',1) target=_self><b><font color=#000000>沪深300</font></b></a> <span id="STK5">3858.52</span> <span id="STK6" class="c1"><img src=/HomeV1/images/down.gif width=8 height=8>181.96</span> <b>香港恒生</b> <span id="STK7">21938.22</span> <span id="STK8" class="c3"><img src=/HomeV1/images/up.gif width=8 height=8>232.66</span> <b>道琼斯</b> <span id="STK9">13414.48</span> <span id="STK10" class="c1"><img src=/HomeV1/images/down.gif width=8 height=8>13.25</span> <b>纳斯达克</b> <span id="STK11">2612.02</span> <span id="STK12" class="c3"><img src=/HomeV1/images/up.gif width=8 height=8>6.67</span> 
<div id="indexdata"><object id="STKData" width="0" height="0" classid="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83" viewastext><param name="FieldDelim" value="F"><param name="DataURL" value="/HomeV1/text/StockIndex.htm"><param name="UseHeader" value="true"></object><input type="hidden" id="STKValue" datasrc="#STKData" datafld="a" name="STKValue"></div>

因为我不是为了介绍正则表达式而写这篇文章的,所以对正则表达式不会做太多的介绍,如果大家对正则表达式有兴趣或想进一步了解的话可以参考:

JAVA中正则表达式的应用
http://www.ibm.com/developerworks/cn/java/l-regp/part1/index.html
http://www.ibm.com/developerworks/cn/java/l-regp/part2/index.html


另外因为为了抓取其他东西,代码已经被我改的面目全非了,暂时就不方便贴出来了,请大家谅解,如果大家有什么疑问的话可以和我联系,我会尽量说明清楚的。
posted on 2007-06-28 22:58 steady 阅读(1779) 评论(2)  编辑  收藏 所属分类: 技术随笔

FeedBack:
# re: Java打造简易股指跟踪系统(2) 2007-07-04 16:36 寒江
剩下的只有定时抓取HTML源码,然后使用正则匹配数据。复杂的通过htmlparser解析HTML,简单的可以通过正则过滤HTML标签 (\s*</?(\w+)(>|[^r][^>]*>)\s*)+|(&nbsp;)+|(\s)+ ,然后在进行数据提取工作

定时可以简单的在while(true)里放个Thread.currentThread().sleep(millis),而不必使用quartz 。

不过老大写出来没几天 ,印花税就涨了。。。
感觉老大还是很会理财的

ORO木大用过,似乎静态的 java.util.regex.Pattern 变量更适合提升程序性能  回复  更多评论
  
# re: Java打造简易股指跟踪系统(2) 2007-07-05 00:21 steady
@寒江
我一般是 sleep(60000),也就是 60 秒。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: