- 浏览: 160215 次
- 性别:
- 来自: 北京
最新评论
-
tanliwei:
Mr-su 写道行业(xingye),why?行是个多音字。
...
利用Java开源库把汉字转拼音 -
u148:
java.io.IOException: Stream clo ...
自己封装的一个编码转换工具类 -
Mr-su:
行业(xingye),why?
利用Java开源库把汉字转拼音 -
364902709:
此意悠悠 写道不可能的,java反射刚出来,最差的时候是正常编 ...
测试Java反射效率 -
此意悠悠:
不可能的,java反射刚出来,最差的时候是正常编程的10倍时间 ...
测试Java反射效率
手动解析HTML是一件很崩溃的事情,sun的swing里也有解析HTML的东东,不过已经是古董了,实在不好拿出来丢Java的人了。
今天要用的是Apache的一个开源项目,html parser。
它的强大不用多说,且看它提供的几个sample吧。
首先去htmlparser.sourceforge.net上去下载,在解压开之后目录里有几个目录,分别存放着src,jars,javadoc之类的,其中bin里有好几个xxx.cmd,用命令行运行那几个脚本,参数就加某个网页的地址就行了。
主意不要拿javaeye的网页做测试哦,不行的,因为sample里的HTTP客户端是用的sun的URLConnection,请求javaeye的话响应的内容是一个空文档,这只是URLConnection的众多bug之一,建议大家不要用哦,如果你只是测试的话那到无所谓咯。
其中stringextractor.cmd是解析出网页内的纯文本内容的,linkextractor.cmd是解析网页里的连接的,非常有用哦。
接下来就要开始编程了,如何使用这个好工具捏?貌似官方并米有详细的文档说明,就这几个sample就已经大致说清楚如何用了。我们找到这几个cmd文件,打开找到其中调用的是那个类,因为它的sample并没有单独拿出来,得要我们自己去它的source里去找。我的建议是在Eclipse的工程里添加那个jar文件,然后把jar文件设置src,这样代码看起来爽一些啦。
小研究一下那几个sample是如何实现的,然后想想你自己的需求,借题发挥吧,这是java程序员的强项了。
上面提到了那几个脚本的参数是网页地址,它的代码里也是在构建Parser对象的时候用的也是url字符串作为参数的,其实如果你想用URLConnection之外的其他Http客户端组件来代替html parser的内置请求方式,也不用担心,因为Parser对象同样提供了html内容作为参数的构建方式:Parser p = Parser.createParser(String html, String charser);
下面是我在项目中用的两个小method,模仿了sample里的代码
/** * 用来抽取html里的连接地址,并转换了相对地址为绝对地址 */ private void extractLinks(URL pageURL, Parser parser) { Map<String, String> links = new HashMap<String, String>(); try { NodeFilter filter = new NodeClassFilter(LinkTag.class); NodeList list = parser.extractAllNodesThatMatch(filter); for (int i = 0; i < list.size(); i++) { LinkTag n = (LinkTag) list.elementAt(i); String link = n.getLink(); if (!n.isHTTPLink()) { continue; } if (link.startsWith("http://")) { try { link = new URL(link).toString(); links.put(HashUtil.md5(link), link); } catch (MalformedURLException e) { continue; } } else { try { link = new URL(pageURL, link).toString(); links.put(HashUtil.md5(link), link); } catch (MalformedURLException e) { continue; } } } } catch (ParserException e) { // TODO 处理异常 e.printStackTrace(); } catch (RuntimeException e) { // TODO 处理异常 e.printStackTrace(); } doc.setDocs(createDoc(links)); }
/** * 抽取html里的文本内容,里面使用了一个自定义的节点访问器,TextExtractVisitor,下面一段有定义 */ private Map<String, Object> extractText(Parser parser) { try { TextExtractVistor textExtractor = new TextExtractVistor(); parser.visitAllNodesWith(textExtractor); doc.getText().setText(textExtractor.getText()); doc.getText().setDigest(textExtractor.getDigest()); doc.getText().setKeywords(textExtractor.getKeywords()); doc.getText().setTitle(textExtractor.getTitle()); return textExtractor.getHashedTextTags(); } catch (ParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
/** * 用来抽取html里文本等相关内容的节点访问器 */ public class TextExtractVistor extends NodeVisitor { StringBuilder textBuf = new StringBuilder(4096); private boolean mIsScript; private boolean mIsStyle; private boolean mIsPre; protected int mCollapseState; private final String NEWLINE = System.getProperty("line.separator"); private final int NEWLINE_SIZE = NEWLINE.length(); private boolean mIsMeta; private boolean mIsH; private boolean isStrong; private StringBuilder digest = new StringBuilder(512); private StringBuilder keywords = new StringBuilder(100); private boolean isTtitle; private String title; private Map<String, Object> textTags = new HashMap<String, Object>(); protected void carriageReturn() { int length; length = textBuf.length(); if ((0 != length) && ((NEWLINE_SIZE <= length) && (!textBuf.substring( length - NEWLINE_SIZE, length).equals(NEWLINE)))) textBuf.append(NEWLINE); mCollapseState = 0; } public void visitStringNode(Text string) { if (!mIsScript && !mIsStyle) { String text = string.getText(); textTags.put(HashUtil.md5(text), null); if (!mIsPre) { text = Translate.decode(text); text = text.replace('\u00a0', ' '); collapse(textBuf, text); } else { textBuf.append(text); if(mIsMeta){ keywords.append(text); }else if(mIsH || isStrong){ digest.append(text); }else if(isTtitle){ title = text; } } } } public void visitTag(Tag tag) { String name = tag.getTagName(); if (name.equalsIgnoreCase("PRE")) mIsPre = true; else if (name.equalsIgnoreCase("SCRIPT")) mIsScript = true; else if (name.equalsIgnoreCase("STYLE")) mIsStyle = true; else if (name.equalsIgnoreCase("META")) mIsMeta = true; else if (name.startsWith("[H|h]")) mIsH = true; else if (name.equalsIgnoreCase("STRONG")) isStrong = true; else if (name.equalsIgnoreCase("TITLE")) isTtitle = true; if (tag.breaksFlow()) carriageReturn(); } public void visitEndTag(Tag tag) { String name; name = tag.getTagName(); if (name.equalsIgnoreCase("PRE")) mIsPre = false; else if (name.equalsIgnoreCase("SCRIPT")) mIsScript = false; else if (name.equalsIgnoreCase("STYLE")) mIsStyle = false; else if (name.equalsIgnoreCase("META")) mIsMeta = false; else if (name.startsWith("[H|h]")) mIsH = false; else if (name.equalsIgnoreCase("STRONG")) isStrong = false; else if (name.equalsIgnoreCase("TITLE")) isTtitle = false; } public String getText() { return textBuf.toString(); } public String getDigest(){ return digest.toString(); } public String getKeywords(){ return keywords.toString(); } public String getTitle(){ return title; } public Map<String, Object> getHashedTextTags(){ return textTags; } protected void collapse(StringBuilder buffer, String string) { int chars; char character; chars = string.length(); if (0 != chars) { for (int i = 0; i < chars; i++) { character = string.charAt(i); switch (character) { // see HTML specification section 9.1 White space // http://www.w3.org/TR/html4/struct/text.html#h-9.1 case '\u0020': case '\u0009': case '\u000C': case '\u200B': case '\r': case '\n': if (0 != mCollapseState) mCollapseState = 1; break; default: if (1 == mCollapseState) buffer.append(' '); mCollapseState = 2; buffer.append(character); } } } } }
评论
额 java搞个html parse 也弄那么麻烦...还是ruby好..
我正准备改行搞ruby捏
发表评论
-
管中窥豹,结合多线程,对于tomcat中servlet加载的一点试探
2010-05-18 23:58 3115对于Servlet自己的生命周 ... -
测试Java反射效率
2010-05-15 23:58 6265测试分为3个方面:1. 实例化效率;2. 方法调用效率;3. ... -
传一本书里的代码
2010-04-13 22:24 1319RT 我把编译产生的bin删了,小了很多 -
想想我們大學都教了啥, 差距呀
2010-03-27 01:02 1074昨天还发现了一个新的概念,叫OAuth,OpenSSO ... -
我也說說OpenSSO
2010-03-24 22:24 1467昨天看到Oracle要關閉OpenSSO的消息,還說要 ... -
考慮用g4j實現一個gmail客戶端
2010-03-20 20:37 968公司考慮信息安全,所以圖允許我們在公司里使用gmail ... -
Gmailer api for java
2010-03-19 16:43 982今天研究了一下子g4j,這個東西,沒弄完,因為公司里面不能隨便 ... -
网站莫名其妙老是挂,原来是线程数太小
2009-11-04 07:54 3252昨天下午我们那个网站忽然变得很慢,我登上去看了下,没发现什么异 ... -
我设计的权限管理方案
2009-06-15 00:34 1751这是给我们学校的某管 ... -
自己做的简单的web服务器
2009-06-14 20:39 2309我最近修的电子商务概论的课程,老师布置的作业,是要做个简单的w ... -
(两年前初学JAVA时写过的一篇文章,发现给我们班同学看还挺有用的)
2009-06-04 04:02 1202最近装了 fedora 7感觉满好,虽然许多人都推崇ubunt ... -
记两次服务器不能启动大原因
2009-05-25 22:44 1102遇到这种很诡异的情况,tomcat无缘无故不能启动,一直处于s ... -
利用Java开源库把汉字转拼音
2009-05-21 02:52 35258最近做的项目,因为下拉框中的项目太多,需要有个过滤的方法。我想 ... -
java 预申请磁盘空间处理大文件
2009-05-09 03:40 1551熟悉电驴和bt的你可能经常看到这些软件可以在下载文件之初就先在 ... -
自己封装的一个编码转换工具类
2009-05-01 23:34 1956java做编码转换有两中方法 1.基于流的编码转换 I ... -
用httpclient模仿firefox发送http请求
2009-04-10 12:18 7120最近需要做爬虫,研究了一下进行做http客户端的东 ... -
在Java中实现伪静态页面
2009-02-18 14:58 3459在Java中做这个事情好像有很多中方案,比较简单的方法是使用U ... -
关于Hibernate懒加载问题的最终解决方案
2009-02-18 14:40 12430Hibernate的强大之处之一是懒加载功能,可以有效的降低数 ...
相关推荐
由于numbers-parser包含从Numbers副本中提取的私有Protobuf定义,因此Numbers numbers-parser无法读取新版本的Numbers,将不可避免地创建.numbers文件。 随着新版本的数字发布,必须执行以下步骤: 在Numbers的新...
dt-sql-parser English |dt-sql-parser是使用构建的SQL Parser项目,主要用于BigData域。 生成了基本的Parser,Visitor和Listener,因此很容易完成语法验证, tokenizer ,遍历AST等功能。 此外,它提供了一些辅助...
用法 import fs from 'fs' import parser from 'iptv-playlist-parser' const playlist = fs . readFileSync ( './playlist.m3u' , { encoding : 'utf-8' } ) const result = parser . parse ( playlist ) console ....
概括此应用程序是使用Maven,Java8,Spring Boot和MySQL构建的。 该应用程序基本上是一个日志文件解析器... 运行installDB.sql创建表并运行以下命令: 使用accesslog文件: java -jar parser.jar --accesslog=/path/to
基本用法是通过调用parseForm($request) ,它将缓冲请求主体并对其进行解析。 <?php use Amp \ Http \ Server \ FormParser ; use Amp \ Http \ Server \ Request ; use Amp \ Http \ Server \ RequestHandler \...
它的本质是对人类过程的基本自动化,该过程在Spice模拟器的GUI上以大约20个不同的频率点读取两个数据类别。 该项目旨在使事情变得更快,更轻松(阅读:自动)。 USAGE $ kicad-sim-parser OPTIONS -h, --help show...
NMEA解析器NMEA Parser 是一个用于解析 NMEA 句子的轻量级库。 该项目使用 C# 4.0 编写,使用 Visual Studio 2010+。 ##支持的句子类型GPRMC ##其他特性“乌鸦飞”的距离比较。... 遵循基本使用文档。
EasyUI入门教程--第03课_parser组件panel组件及如何使用组件自带的属性、事件、方法.avi,这是由孙宇老师录制的视频,现在很难找了,讲得很详细,授人以鱼,不如授人以渔。 第01课(大概介绍一下easyui,和组织...
基本用法const fs = require ( 'fs' ) ;const Parser = require ( 'qrcode-image-parser' ) ;let data = fs . readFileSync ( './login.jpg' ) ;Parser . parse ( data , ( err , parsed ) => { console . log ( ...
基本用法: use lib_ruby_parser :: {Parser, ParserOptions, debug_level};fn main () -> Result <(), Box < dyn>> { let options = ParserOptions { buffer_name: "(eval)" . to_string (), debug: debug_...
html解析器简单HTML到JSON解析器,使用Regexp和String.indexOf安装npm install htmlstr-parser基本用法var html = "<div xss=removed>1<p>2<br><a href='http://www.baidu.com'>3</a></p><p>2</p></div>"htmlParser ...
FileParser FileParser是一个.NET库,旨在逐行读取文本文件,将每行的内容保存为基本类型vars(int,double,string等)。 直到v1.4.x为止,都支持.NET Framework 4.6。 在v1.6.x之前支持.NET Standard 2.0和2.1。 ...
这个模块是完全从提取的,它基本上是轻量级的版本,具有路径排名支持。 安装 npm i @egoist/path-parser 用法 创建路径解析器: import { createParser } from '@egoist/path-parser' const parser = createParser...
用法 const parser = new Parser . PredicateParser ( ) ; const predicate = parser . parse ( "firstName==Paul;age==25" ) ; const matches = predicate ( { firstName : "Paul" , age : 23 } ) ; assertFalse ...
特征使用ANTLR4解析功能将配置文件转换为AST树JavaCC同样可用(不建议使用) 重建配置文件并将其转储回* .conf 嵌套块支持如果语句支持位置/重写/如果语句支持内未引用的正则表达式评论支持安装将以下依赖项添加到您...
example.py:一些使用示例(用法:python3 example.py) example_output.txt:以txt格式输出example.py脚本 example_grammar * .txt:一些示例语法 作者 Iker García Ferrero - ikergarcia1996 使用例 # ...
基本用法 您可以在tests目录中找到许多有关如何使用DOM解析器及其任何部分(您很可能永远不会接触)的示例。 测试是使用PHPUnit完成的,非常小,每行几行,是一个很好的起点。 鉴于此,我仍将展示一些有关如何使用该...
这使数字的配置更具可读性,以下是有效的严格CSON文件: cachedData : refreshIntervalMs : 5 * 60 * 1000安装npm install --save cson-parser 用法CSON = require ' cson-parser '# This will print { a: '123' }...
对于.ipa ,解析info.plist和embedded.mobileprovision文件,读取info.plist文件中的所有基本信息,包括ipa文件的图标(已经处理了压碎的png)。 致谢 该项目基于 , 和 。 安装 npm install --save reiko-parser ...
基本用法 React使用 预设值 创建自己的预设 HTML预设 React预设 React使用 成分 渲染道具 PostHTML的用法 创建插件 基准测试 基本用法 npm i @bbob/core @bbob/html @bbob/preset-html5 import bbobHTML from '@...